@@ -100,46 +100,39 @@ unittest
100100 hash = crc.finish();
101101}
102102
103- private immutable uint [256 ] crc32_table =
104- [
105- 0x00000000 ,0x77073096 ,0xee0e612c ,0x990951ba ,0x076dc419 ,0x706af48f ,0xe963a535 ,
106- 0x9e6495a3 ,0x0edb8832 ,0x79dcb8a4 ,0xe0d5e91e ,0x97d2d988 ,0x09b64c2b ,0x7eb17cbd ,
107- 0xe7b82d07 ,0x90bf1d91 ,0x1db71064 ,0x6ab020f2 ,0xf3b97148 ,0x84be41de ,0x1adad47d ,
108- 0x6ddde4eb ,0xf4d4b551 ,0x83d385c7 ,0x136c9856 ,0x646ba8c0 ,0xfd62f97a ,0x8a65c9ec ,
109- 0x14015c4f ,0x63066cd9 ,0xfa0f3d63 ,0x8d080df5 ,0x3b6e20c8 ,0x4c69105e ,0xd56041e4 ,
110- 0xa2677172 ,0x3c03e4d1 ,0x4b04d447 ,0xd20d85fd ,0xa50ab56b ,0x35b5a8fa ,0x42b2986c ,
111- 0xdbbbc9d6 ,0xacbcf940 ,0x32d86ce3 ,0x45df5c75 ,0xdcd60dcf ,0xabd13d59 ,0x26d930ac ,
112- 0x51de003a ,0xc8d75180 ,0xbfd06116 ,0x21b4f4b5 ,0x56b3c423 ,0xcfba9599 ,0xb8bda50f ,
113- 0x2802b89e ,0x5f058808 ,0xc60cd9b2 ,0xb10be924 ,0x2f6f7c87 ,0x58684c11 ,0xc1611dab ,
114- 0xb6662d3d ,0x76dc4190 ,0x01db7106 ,0x98d220bc ,0xefd5102a ,0x71b18589 ,0x06b6b51f ,
115- 0x9fbfe4a5 ,0xe8b8d433 ,0x7807c9a2 ,0x0f00f934 ,0x9609a88e ,0xe10e9818 ,0x7f6a0dbb ,
116- 0x086d3d2d ,0x91646c97 ,0xe6635c01 ,0x6b6b51f4 ,0x1c6c6162 ,0x856530d8 ,0xf262004e ,
117- 0x6c0695ed ,0x1b01a57b ,0x8208f4c1 ,0xf50fc457 ,0x65b0d9c6 ,0x12b7e950 ,0x8bbeb8ea ,
118- 0xfcb9887c ,0x62dd1ddf ,0x15da2d49 ,0x8cd37cf3 ,0xfbd44c65 ,0x4db26158 ,0x3ab551ce ,
119- 0xa3bc0074 ,0xd4bb30e2 ,0x4adfa541 ,0x3dd895d7 ,0xa4d1c46d ,0xd3d6f4fb ,0x4369e96a ,
120- 0x346ed9fc ,0xad678846 ,0xda60b8d0 ,0x44042d73 ,0x33031de5 ,0xaa0a4c5f ,0xdd0d7cc9 ,
121- 0x5005713c ,0x270241aa ,0xbe0b1010 ,0xc90c2086 ,0x5768b525 ,0x206f85b3 ,0xb966d409 ,
122- 0xce61e49f ,0x5edef90e ,0x29d9c998 ,0xb0d09822 ,0xc7d7a8b4 ,0x59b33d17 ,0x2eb40d81 ,
123- 0xb7bd5c3b ,0xc0ba6cad ,0xedb88320 ,0x9abfb3b6 ,0x03b6e20c ,0x74b1d29a ,0xead54739 ,
124- 0x9dd277af ,0x04db2615 ,0x73dc1683 ,0xe3630b12 ,0x94643b84 ,0x0d6d6a3e ,0x7a6a5aa8 ,
125- 0xe40ecf0b ,0x9309ff9d ,0x0a00ae27 ,0x7d079eb1 ,0xf00f9344 ,0x8708a3d2 ,0x1e01f268 ,
126- 0x6906c2fe ,0xf762575d ,0x806567cb ,0x196c3671 ,0x6e6b06e7 ,0xfed41b76 ,0x89d32be0 ,
127- 0x10da7a5a ,0x67dd4acc ,0xf9b9df6f ,0x8ebeeff9 ,0x17b7be43 ,0x60b08ed5 ,0xd6d6a3e8 ,
128- 0xa1d1937e ,0x38d8c2c4 ,0x4fdff252 ,0xd1bb67f1 ,0xa6bc5767 ,0x3fb506dd ,0x48b2364b ,
129- 0xd80d2bda ,0xaf0a1b4c ,0x36034af6 ,0x41047a60 ,0xdf60efc3 ,0xa867df55 ,0x316e8eef ,
130- 0x4669be79 ,0xcb61b38c ,0xbc66831a ,0x256fd2a0 ,0x5268e236 ,0xcc0c7795 ,0xbb0b4703 ,
131- 0x220216b9 ,0x5505262f ,0xc5ba3bbe ,0xb2bd0b28 ,0x2bb45a92 ,0x5cb36a04 ,0xc2d7ffa7 ,
132- 0xb5d0cf31 ,0x2cd99e8b ,0x5bdeae1d ,0x9b64c2b0 ,0xec63f226 ,0x756aa39c ,0x026d930a ,
133- 0x9c0906a9 ,0xeb0e363f ,0x72076785 ,0x05005713 ,0x95bf4a82 ,0xe2b87a14 ,0x7bb12bae ,
134- 0x0cb61b38 ,0x92d28e9b ,0xe5d5be0d ,0x7cdcefb7 ,0x0bdbdf21 ,0x86d3d2d4 ,0xf1d4e242 ,
135- 0x68ddb3f8 ,0x1fda836e ,0x81be16cd ,0xf6b9265b ,0x6fb077e1 ,0x18b74777 ,0x88085ae6 ,
136- 0xff0f6a70 ,0x66063bca ,0x11010b5c ,0x8f659eff ,0xf862ae69 ,0x616bffd3 ,0x166ccf45 ,
137- 0xa00ae278 ,0xd70dd2ee ,0x4e048354 ,0x3903b3c2 ,0xa7672661 ,0xd06016f7 ,0x4969474d ,
138- 0x3e6e77db ,0xaed16a4a ,0xd9d65adc ,0x40df0b66 ,0x37d83bf0 ,0xa9bcae53 ,0xdebb9ec5 ,
139- 0x47b2cf7f ,0x30b5ffe9 ,0xbdbdf21c ,0xcabac28a ,0x53b39330 ,0x24b4a3a6 ,0xbad03605 ,
140- 0xcdd70693 ,0x54de5729 ,0x23d967bf ,0xb3667a2e ,0xc4614ab8 ,0x5d681b02 ,0x2a6f2b94 ,
141- 0xb40bbe37 ,0xc30c8ea1 ,0x5a05df1b ,0x2d02ef8d
142- ];
103+ private uint [256 ][8 ] genTables (uint polynomial)
104+ {
105+ uint [256 ][8 ] res = void ;
106+
107+ foreach (i; 0 .. 0x100 )
108+ {
109+ uint crc = i;
110+ foreach (_; 0 .. 8 )
111+ crc = (crc >> 1 ) ^ (- int (crc & 1 ) & polynomial);
112+ res[0 ][i] = crc;
113+ }
114+
115+ foreach (i; 0 .. 0x100 )
116+ {
117+ res[1 ][i] = (res[0 ][i] >> 8 ) ^ res[0 ][res[0 ][i] & 0xFF ];
118+ res[2 ][i] = (res[1 ][i] >> 8 ) ^ res[0 ][res[1 ][i] & 0xFF ];
119+ res[3 ][i] = (res[2 ][i] >> 8 ) ^ res[0 ][res[2 ][i] & 0xFF ];
120+
121+ res[4 ][i] = (res[3 ][i] >> 8 ) ^ res[0 ][res[3 ][i] & 0xFF ];
122+ res[5 ][i] = (res[4 ][i] >> 8 ) ^ res[0 ][res[4 ][i] & 0xFF ];
123+ res[6 ][i] = (res[5 ][i] >> 8 ) ^ res[0 ][res[5 ][i] & 0xFF ];
124+ res[7 ][i] = (res[6 ][i] >> 8 ) ^ res[0 ][res[6 ][i] & 0xFF ];
125+ }
126+ return res;
127+ }
128+
129+ private static immutable uint [256 ][8 ] crc32Tables = genTables(0xEDB88320 );
130+
131+ unittest
132+ {
133+ auto tables = genTables(0xEDB88320 );
134+ assert (tables[0 ][0 ] == 0x00000000 && tables[0 ][$ - 1 ] == 0x2d02ef8d && tables[7 ][$ - 1 ] == 0x264b06e6 );
135+ }
143136
144137/**
145138 * Template API CRC32 implementation.
@@ -159,8 +152,48 @@ struct CRC32
159152 */
160153 void put (scope const (ubyte )[] data... ) @trusted pure nothrow @nogc
161154 {
162- foreach (val; data)
163- _state = (_state >> 8 ) ^ crc32_table[cast (ubyte )_state ^ val];
155+ uint crc = _state;
156+ // process eight bytes at once
157+ while (data.length >= 8 )
158+ {
159+ // Use byte-wise reads to support architectures without HW support
160+ // for unaligned reads. This can be optimized by compilers to a single
161+ // 32-bit read if unaligned reads are supported.
162+ // DMD is not able to do this optimization though, so explicitly
163+ // do unaligned reads for DMD's architectures.
164+ version (X86 )
165+ enum hasLittleEndianUnalignedReads = true ;
166+ else version (X86_64 )
167+ enum hasLittleEndianUnalignedReads = true ;
168+ else
169+ enum hasLittleEndianUnalignedReads = false ; // leave decision to optimizer
170+ static if (hasLittleEndianUnalignedReads)
171+ {
172+ uint one = (cast (uint * ) data.ptr)[0 ] ^ crc;
173+ uint two = (cast (uint * ) data.ptr)[1 ];
174+ }
175+ else
176+ {
177+ uint one = (data.ptr[3 ] << 24 | data.ptr[2 ] << 16 | data.ptr[1 ] << 8 | data.ptr[0 ]) ^ crc;
178+ uint two = (data.ptr[7 ] << 24 | data.ptr[6 ] << 16 | data.ptr[5 ] << 8 | data.ptr[4 ]);
179+ }
180+
181+ crc =
182+ crc32Tables[0 ][two >> 24 ] ^
183+ crc32Tables[1 ][(two >> 16 ) & 0xFF ] ^
184+ crc32Tables[2 ][(two >> 8 ) & 0xFF ] ^
185+ crc32Tables[3 ][two & 0xFF ] ^
186+ crc32Tables[4 ][one >> 24 ] ^
187+ crc32Tables[5 ][(one >> 16 ) & 0xFF ] ^
188+ crc32Tables[6 ][(one >> 8 ) & 0xFF ] ^
189+ crc32Tables[7 ][one & 0xFF ];
190+
191+ data = data[8 .. $];
192+ }
193+ // remaining 1 to 7 bytes
194+ foreach (d; data)
195+ crc = (crc >> 8 ) ^ crc32Tables[0 ][(crc & 0xFF ) ^ d];
196+ _state = crc;
164197 }
165198 // /
166199 unittest
0 commit comments