C / C ++, 306 295 bajtów
#define C(c)((c)>>1^((c)&1?0xEDB88320L:0))
#define K(c)(C(C(C(C(C(C(C(C(c))))))))),
#define F(h,l)K((h)|(l+0))K((h)|(l+1))K((h)|(l+2))K((h)|(l+3))
#define R(h)F(h<<4,0)F(h<<4,4)F(h<<4,8)F(h<<4,12)
unsigned long crc_table[]={R(0)R(1)R(2)R(3)R(4)R(5)R(6)R(7)R(8)R(9)R(10)R(11)R(12)R(13)R(14)R(15)};
Pracując w odwrotnej kolejności, otrzymujemy niepodpisaną długą tablicę o nazwie crc_table. Możemy pominąć rozmiar tablicy, ponieważ makra zapewnią, że w tablicy jest dokładnie 256 elementów. Inicjujemy tablicę za pomocą 16 „wierszy” danych, używając 16 wywołań makra R.
Każde wywołanie R rozwija się do czterech fragmentów (makro F) czterech stałych (makro K), co daje 16 „kolumn” danych.
Makro K jest rozwiniętą pętlą indeksowaną przez k w kodzie z pierwotnego pytania. Aktualizuje wartość c osiem razy, wywołując makro C.
To rozwiązanie oparte na preprocesorze zużywa sporo pamięci podczas rozwijania makr. Próbowałem to zrobić nieco krócej, mając dodatkowy poziom ekspansji makr, a mój kompilator zwymiotował. Powyższy kod kompiluje się (powoli) zarówno z Visual C ++ 2012, jak i g ++ 4.5.3 pod Cygwin (Windows 7 64 bit 8 GB RAM).
Edytować:
Powyższy fragment ma 295 bajtów, w tym białe znaki. Po rozwinięciu wszystkich makr oprócz C rośnie do 9 918 bajtów. W miarę rozszerzania każdego poziomu makra C rozmiar szybko rośnie:
- 25 182
- 54,174
- 109,086
- 212,766
- 407,838
- 773,406
- 1 455,390
- 2 721 054
Do czasu rozwinięcia wszystkich makr ten mały plik 295 bajtów rozwija się do ponad 2,7 megabajtów kodu, który należy skompilować, aby wygenerować oryginalną tablicę 1024 bajtów (przy założeniu 32 bitowych długich wartości bez znaku)!
Kolejna edycja:
Zmodyfikowałem makro C na podstawie makra z innej odpowiedzi, aby wycisnąć dodatkowe 11 bajtów, i znacznie zmniejszyłem pełny rozmiar makra. Chociaż 2,7 MB nie jest tak złe jak 54 MB (poprzedni końcowy rozmiar wszystkich rozszerzeń makr), nadal jest znaczące.