CRC32Stream.st
changeset 2570 55ce3e8bd7dc
parent 2569 abfbf6f1682b
child 2571 12d5e280eea1
equal deleted inserted replaced
2569:abfbf6f1682b 2570:55ce3e8bd7dc
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 "{ Package: 'stx:libbasic2' }"
    12 "{ Package: 'stx:libbasic2' }"
    13 
    13 
    14 HashStream subclass:#CRC32Stream
    14 HashStream subclass:#CRC32Stream
    15 	instanceVariableNames:'crc'
    15 	instanceVariableNames:'crc generatorPolynom crcTable'
    16 	classVariableNames:'CrcTable'
    16 	classVariableNames:'CrcTables'
    17 	poolDictionaries:''
    17 	poolDictionaries:''
    18 	category:'System-Crypt-Hashing'
    18 	category:'System-Crypt-Hashing'
    19 !
    19 !
    20 
    20 
    21 !CRC32Stream class methodsFor:'documentation'!
    21 !CRC32Stream class methodsFor:'documentation'!
    35 !
    35 !
    36 
    36 
    37 documentation
    37 documentation
    38 "
    38 "
    39     Standard CRC method as defined by ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-T-V42]. 
    39     Standard CRC method as defined by ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-T-V42]. 
    40     The CRC polynomial employed is
    40     The default CRC polynomial employed is
    41 
    41 
    42         x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
    42         x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1
    43         (or 16r04C11DB7)
    43         (or 16r04C11DB7)
       
    44 
       
    45     You can also create an instace perforing the Castagnioli CRC-32C 
       
    46     (used in iSCSI & SCTP, G.hn payload, SSE4.2):
       
    47 
       
    48         self newCrc32c
       
    49 
       
    50         x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1 
    44 
    51 
    45     Use CRC to protect against communication errors;
    52     Use CRC to protect against communication errors;
    46     do NOT use CRC for cryptography - use SHA1Stream or MD5Stream instead.
    53     do NOT use CRC for cryptography - use SHA1Stream or MD5Stream instead.
    47 
    54 
    48     Notice that this CRC is also used with PNG images - therefore, its performance 
    55     Notice that this CRC is also used with PNG images - therefore, its performance 
   124 "
   131 "
   125 ! !
   132 ! !
   126 
   133 
   127 !CRC32Stream class methodsFor:'initialization'!
   134 !CRC32Stream class methodsFor:'initialization'!
   128 
   135 
       
   136 crcTableFor:generatorPolynomInteger
       
   137     |crcTable|
       
   138 
       
   139     crcTable := (CrcTables at:generatorPolynomInteger ifAbsent:nil). 
       
   140     crcTable isNil ifTrue:[
       
   141         crcTable := IntegerArray new:256.
       
   142 
       
   143         0 to:255 do:[:count| |i|
       
   144             i := count.
       
   145             8 timesRepeat:[
       
   146                 (i bitTest:1) ifTrue:[
       
   147                     i := generatorPolynomInteger bitXor:(i bitShift:-1)
       
   148                 ] ifFalse:[
       
   149                     i := i bitShift:-1
       
   150                 ]
       
   151             ].
       
   152             crcTable at:count+1 put:i.
       
   153         ].
       
   154         CrcTables at:generatorPolynomInteger put:crcTable.
       
   155     ].
       
   156     ^ crcTable.
       
   157 !
       
   158 
   129 initialize
   159 initialize
   130 
   160     CrcTables := Dictionary new.
   131     CrcTable := IntegerArray new:256.
   161 ! !
   132 
   162 
   133     0 to:255 do:[:count| |i|
   163 !CRC32Stream class methodsFor:'instance creation'!
   134         i := count.
   164 
   135         8 timesRepeat:[
   165 generatorPolynom:anInteger
   136             (i bitTest:1) ifTrue:[
   166     ^ self basicNew generatorPolynom:anInteger
   137 "/                i := 16r1EDC6F41 bitXor:(i bitShift:-1)
   167 
   138                 i := 16rEDB88320 bitXor:(i bitShift:-1)
   168     "
   139             ] ifFalse:[
   169        self assert:((self generatorPolynom:16r82F63B78)
   140                 i := i bitShift:-1
   170                                 nextPut:'123456789';
   141             ]
   171                                 hashValue)    = 16rE3069283
   142         ].
   172     "
   143         CrcTable at:count+1 put:i.
   173 !
   144     ].
   174 
   145 
   175 newCrc32C
   146     "
   176     "return an instance of the Castagnoli CRC-32
   147       self initialize
   177         x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1 
       
   178      (used in iSCSI & SCTP, G.hn payload, SSE4.2)"
       
   179 
       
   180     ^ self basicNew generatorPolynom:16r82F63B78
       
   181 
       
   182     "
       
   183        self assert:((self newCrc32C)
       
   184                                 nextPut:'123456789';
       
   185                                 hashValue)    = 16rE3069283
   148     "
   186     "
   149 ! !
   187 ! !
   150 
   188 
   151 !CRC32Stream class methodsFor:'testing'!
   189 !CRC32Stream class methodsFor:'testing'!
   152 
   190 
   178     "
   216     "
   179      self test
   217      self test
   180     "
   218     "
   181 ! !
   219 ! !
   182 
   220 
       
   221 !CRC32Stream methodsFor:'accessing'!
       
   222 
       
   223 generatorPolynom
       
   224     "answer the generator polynom"
       
   225 
       
   226     ^ generatorPolynom
       
   227 !
       
   228 
       
   229 generatorPolynom:anInteger
       
   230     generatorPolynom := anInteger.
       
   231     crc := 16rFFFFFFFF.
       
   232     crcTable := self class crcTableFor:generatorPolynom.
       
   233 ! !
       
   234 
   183 !CRC32Stream methodsFor:'initialization'!
   235 !CRC32Stream methodsFor:'initialization'!
   184 
   236 
   185 initialize
   237 initialize
   186     "initialize the CRC"
   238     "initialize the CRC to CRC-32 ITU-T:
   187 
   239         x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1"
   188     crc := 16rFFFFFFFF.
   240 
       
   241     self generatorPolynom:16rEDB88320
   189 ! !
   242 ! !
   190 
   243 
   191 !CRC32Stream methodsFor:'queries'!
   244 !CRC32Stream methodsFor:'queries'!
   192 
   245 
   193 hashValue
   246 hashValue
   230                 _crc = (unsigned) (__intVal( __INST(crc) ));
   283                 _crc = (unsigned) (__intVal( __INST(crc) ));
   231             } else {
   284             } else {
   232                 _crc = __unsignedLongIntVal( __INST(crc) );
   285                 _crc = __unsignedLongIntVal( __INST(crc) );
   233             }
   286             }
   234 
   287 
   235             _crcTable = __integerArrayVal( @global(CrcTable) );
   288             _crcTable = __integerArrayVal( __INST(crcTable) );
   236 
   289 
   237             while (n > 3) {
   290             while (n > 3) {
   238                 unsigned _idx;
   291                 unsigned _idx;
   239 
   292 
   240                 _idx = (_crc ^ cp[0]) & 0xFF;
   293                 _idx = (_crc ^ cp[0]) & 0xFF;
   275 %}.
   328 %}.
   276     arg isByteCollection ifTrue:[
   329     arg isByteCollection ifTrue:[
   277         argSize := arg size.
   330         argSize := arg size.
   278         1 to:argSize do:[:n|
   331         1 to:argSize do:[:n|
   279             byte := arg byteAt:n.
   332             byte := arg byteAt:n.
   280             crc := (CrcTable at:((crc bitXor:byte) bitAnd:16rFF)+1) 
   333             crc := (crcTable at:((crc bitXor:byte) bitAnd:16rFF)+1) 
   281                    bitXor:(crc bitShift:-8).
   334                    bitXor:(crc bitShift:-8).
   282         ].
   335         ].
   283         ^ self.
   336         ^ self.
   284     ].
   337     ].
   285 
   338 
   286     arg isCharacter ifTrue:[
   339     arg isCharacter ifTrue:[
   287         byte := arg codePoint.
   340         byte := arg codePoint.
   288         byte < 256 ifTrue:[
   341         byte < 256 ifTrue:[
   289             crc := (CrcTable at:((crc bitXor:byte) bitAnd:16rFF)+1) 
   342             crc := (crcTable at:((crc bitXor:byte) bitAnd:16rFF)+1) 
   290                    bitXor:(crc bitShift:-8).
   343                    bitXor:(crc bitShift:-8).
   291             ^ self.
   344             ^ self.
   292         ].
   345         ].
   293         byte digitBytes do:[:eachByte|
   346         byte digitBytes do:[:eachByte|
   294             crc := (CrcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1) 
   347             crc := (crcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1) 
   295                    bitXor:(crc bitShift:-8).
   348                    bitXor:(crc bitShift:-8).
   296         ].
   349         ].
   297         ^ self.
   350         ^ self.
   298     ].
   351     ].
   299 
   352 
   300     arg isInteger ifTrue:[
   353     arg isInteger ifTrue:[
   301         arg < 256 ifTrue:[
   354         arg < 256 ifTrue:[
   302             crc := (CrcTable at:((crc bitXor:arg) bitAnd:16rFF)+1) 
   355             crc := (crcTable at:((crc bitXor:arg) bitAnd:16rFF)+1) 
   303                    bitXor:(crc bitShift:-8).
   356                    bitXor:(crc bitShift:-8).
   304             ^ self.
   357             ^ self.
   305         ].
   358         ].
   306         arg digitBytes do:[:eachByte|
   359         arg digitBytes do:[:eachByte|
   307             crc := (CrcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1) 
   360             crc := (crcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1) 
   308                    bitXor:(crc bitShift:-8).
   361                    bitXor:(crc bitShift:-8).
   309         ].
   362         ].
   310         ^ self.
   363         ^ self.
   311     ].
   364     ].
   312 
   365 
   321 ! !
   374 ! !
   322 
   375 
   323 !CRC32Stream class methodsFor:'documentation'!
   376 !CRC32Stream class methodsFor:'documentation'!
   324 
   377 
   325 version
   378 version
   326     ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.14 2011-05-13 10:42:54 stefan Exp $'
   379     ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.15 2011-05-13 15:21:46 stefan Exp $'
   327 !
   380 !
   328 
   381 
   329 version_CVS
   382 version_CVS
   330     ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.14 2011-05-13 10:42:54 stefan Exp $'
   383     ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.15 2011-05-13 15:21:46 stefan Exp $'
   331 ! !
   384 ! !
   332 
   385 
   333 CRC32Stream initialize!
   386 CRC32Stream initialize!