C / C ++, 306 295 byte
#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)};
Làm việc ngược lại, chúng tôi kết thúc với một mảng dài không dấu có tên là crc_table. Chúng ta có thể bỏ qua kích thước của mảng vì các macro sẽ đảm bảo có chính xác 256 phần tử trong mảng. Chúng tôi khởi tạo mảng với 16 'hàng' dữ liệu bằng cách sử dụng 16 yêu cầu của macro R.
Mỗi lệnh gọi R mở rộng thành bốn đoạn (macro F) gồm bốn hằng số (macro K) cho tổng số 16 'cột' dữ liệu.
Macro K là vòng lặp không được kiểm soát được lập chỉ mục bởi k trong mã từ câu hỏi ban đầu. Nó cập nhật giá trị c tám lần bằng cách gọi macro C.
Giải pháp dựa trên bộ tiền xử lý này sử dụng khá nhiều bộ nhớ trong quá trình mở rộng macro. Tôi đã cố gắng làm cho nó ngắn hơn một chút bằng cách có thêm một mức độ mở rộng macro và trình biên dịch của tôi đã bị hỏng. Đoạn mã trên biên dịch (chậm) với cả Visual C ++ 2012 và g ++ 4.5.3 dưới Cygwin (RAM Windows 7 64 bit 8GB).
Biên tập:
Đoạn trên là 295 byte bao gồm cả khoảng trắng. Sau khi mở rộng tất cả các macro ngoại trừ C, nó tăng lên 9,918 byte. Khi mỗi cấp độ macro C được mở rộng, kích thước sẽ tăng lên nhanh chóng:
- 25.182
- 54.174
- 109,086
- 212.766
- 407.838
- 773.406
- 1.455.390
- 2.721.054
Vì vậy, tại thời điểm tất cả các macro đã được mở rộng, tệp 295 byte nhỏ đó sẽ mở rộng thành hơn 2,7 megabyte mã phải được biên dịch để tạo ra mảng 1024 byte ban đầu (giả sử các giá trị dài không dấu 32 bit)!
Chỉnh sửa khác:
Tôi đã sửa đổi macro C dựa trên một macro từ một câu trả lời khác để vắt thêm 11 byte và giảm đáng kể kích thước macro mở rộng đầy đủ. Mặc dù 2,7 MB không tệ bằng 54 MB (kích thước cuối cùng trước đó của tất cả các mở rộng macro), nhưng nó vẫn rất đáng kể.