--- a/CRC32Stream.st Fri May 13 12:42:54 2011 +0200
+++ b/CRC32Stream.st Fri May 13 17:21:46 2011 +0200
@@ -12,8 +12,8 @@
"{ Package: 'stx:libbasic2' }"
HashStream subclass:#CRC32Stream
- instanceVariableNames:'crc'
- classVariableNames:'CrcTable'
+ instanceVariableNames:'crc generatorPolynom crcTable'
+ classVariableNames:'CrcTables'
poolDictionaries:''
category:'System-Crypt-Hashing'
!
@@ -37,11 +37,18 @@
documentation
"
Standard CRC method as defined by ISO 3309 [ISO-3309] or ITU-T V.42 [ITU-T-V42].
- The CRC polynomial employed is
+ The default CRC polynomial employed is
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
(or 16r04C11DB7)
+ You can also create an instace perforing the Castagnioli CRC-32C
+ (used in iSCSI & SCTP, G.hn payload, SSE4.2):
+
+ self newCrc32c
+
+ x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1
+
Use CRC to protect against communication errors;
do NOT use CRC for cryptography - use SHA1Stream or MD5Stream instead.
@@ -126,25 +133,56 @@
!CRC32Stream class methodsFor:'initialization'!
-initialize
+crcTableFor:generatorPolynomInteger
+ |crcTable|
- CrcTable := IntegerArray new:256.
+ crcTable := (CrcTables at:generatorPolynomInteger ifAbsent:nil).
+ crcTable isNil ifTrue:[
+ crcTable := IntegerArray new:256.
- 0 to:255 do:[:count| |i|
- i := count.
- 8 timesRepeat:[
- (i bitTest:1) ifTrue:[
-"/ i := 16r1EDC6F41 bitXor:(i bitShift:-1)
- i := 16rEDB88320 bitXor:(i bitShift:-1)
- ] ifFalse:[
- i := i bitShift:-1
- ]
+ 0 to:255 do:[:count| |i|
+ i := count.
+ 8 timesRepeat:[
+ (i bitTest:1) ifTrue:[
+ i := generatorPolynomInteger bitXor:(i bitShift:-1)
+ ] ifFalse:[
+ i := i bitShift:-1
+ ]
+ ].
+ crcTable at:count+1 put:i.
].
- CrcTable at:count+1 put:i.
+ CrcTables at:generatorPolynomInteger put:crcTable.
].
+ ^ crcTable.
+!
+
+initialize
+ CrcTables := Dictionary new.
+! !
+
+!CRC32Stream class methodsFor:'instance creation'!
+
+generatorPolynom:anInteger
+ ^ self basicNew generatorPolynom:anInteger
"
- self initialize
+ self assert:((self generatorPolynom:16r82F63B78)
+ nextPut:'123456789';
+ hashValue) = 16rE3069283
+ "
+!
+
+newCrc32C
+ "return an instance of the Castagnoli CRC-32
+ x32 + x28 + x27 + x26 + x25 + x23 + x22 + x20 + x19 + x18 + x14 + x13 + x11 + x10 + x9 + x8 + x6 + 1
+ (used in iSCSI & SCTP, G.hn payload, SSE4.2)"
+
+ ^ self basicNew generatorPolynom:16r82F63B78
+
+ "
+ self assert:((self newCrc32C)
+ nextPut:'123456789';
+ hashValue) = 16rE3069283
"
! !
@@ -180,12 +218,27 @@
"
! !
+!CRC32Stream methodsFor:'accessing'!
+
+generatorPolynom
+ "answer the generator polynom"
+
+ ^ generatorPolynom
+!
+
+generatorPolynom:anInteger
+ generatorPolynom := anInteger.
+ crc := 16rFFFFFFFF.
+ crcTable := self class crcTableFor:generatorPolynom.
+! !
+
!CRC32Stream methodsFor:'initialization'!
initialize
- "initialize the CRC"
+ "initialize the CRC to CRC-32 ITU-T:
+ 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"
- crc := 16rFFFFFFFF.
+ self generatorPolynom:16rEDB88320
! !
!CRC32Stream methodsFor:'queries'!
@@ -232,7 +285,7 @@
_crc = __unsignedLongIntVal( __INST(crc) );
}
- _crcTable = __integerArrayVal( @global(CrcTable) );
+ _crcTable = __integerArrayVal( __INST(crcTable) );
while (n > 3) {
unsigned _idx;
@@ -277,7 +330,7 @@
argSize := arg size.
1 to:argSize do:[:n|
byte := arg byteAt:n.
- crc := (CrcTable at:((crc bitXor:byte) bitAnd:16rFF)+1)
+ crc := (crcTable at:((crc bitXor:byte) bitAnd:16rFF)+1)
bitXor:(crc bitShift:-8).
].
^ self.
@@ -286,12 +339,12 @@
arg isCharacter ifTrue:[
byte := arg codePoint.
byte < 256 ifTrue:[
- crc := (CrcTable at:((crc bitXor:byte) bitAnd:16rFF)+1)
+ crc := (crcTable at:((crc bitXor:byte) bitAnd:16rFF)+1)
bitXor:(crc bitShift:-8).
^ self.
].
byte digitBytes do:[:eachByte|
- crc := (CrcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1)
+ crc := (crcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1)
bitXor:(crc bitShift:-8).
].
^ self.
@@ -299,12 +352,12 @@
arg isInteger ifTrue:[
arg < 256 ifTrue:[
- crc := (CrcTable at:((crc bitXor:arg) bitAnd:16rFF)+1)
+ crc := (crcTable at:((crc bitXor:arg) bitAnd:16rFF)+1)
bitXor:(crc bitShift:-8).
^ self.
].
arg digitBytes do:[:eachByte|
- crc := (CrcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1)
+ crc := (crcTable at:((crc bitXor:eachByte) bitAnd:16rFF)+1)
bitXor:(crc bitShift:-8).
].
^ self.
@@ -323,11 +376,11 @@
!CRC32Stream class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.14 2011-05-13 10:42:54 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.15 2011-05-13 15:21:46 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.14 2011-05-13 10:42:54 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic2/CRC32Stream.st,v 1.15 2011-05-13 15:21:46 stefan Exp $'
! !
CRC32Stream initialize!