Parameters:
- sStr Input string
- Poly Polynomial
- Bits Width of output in bits. This should be 0 if Polynomial is a reflected value.
- Init Initial CRC value
- Xorout Output CRC value will be XORed with this value.
Where can I find the parameters?
CRC RevEng provides CRC parameters in these 3 pages:
How to interpret CRC RevEng parameters?
Here follows two examples:
CRC-16/CDMA2000
width=16 poly=0xc867 init=0xffff refin=false refout=false xorout=0x0000 check=0x4c06 residue=0x0000 name="CRC-16/CDMA2000"
In the above line, you see refin=false which means polynomial can be used in its normal state.
*refin means reflected input
Pass the 4 four parameters in following order: poly, width, init, xorout
*refin means reflected input
Pass the 4 four parameters in following order: poly, width, init, xorout
Code: Select all
MsgBox % aCrc("AutoHotkey", 0xc867, 16, 0xffff, 0x0000) ; 0x8ABF
CRC-16/ARC
width=16 poly=0x8005 init=0x0000 refin=true refout=true xorout=0x0000 check=0xbb3d residue=0x0000 name="CRC-16/ARC"
In the above line, we see refin=true which means polynomial should be reflected before use.
What does "reflected" mean?
If you write down the bits of a number in a paper and see its refection in a mirror, the bits will be reversed.
In same manner, the polynomial 0x8005 should be reversed to 0xA001
Pass the 4 four parameters in following order: refpoly, 0, init, xorout
*Width should be 0 or else aCrc() wouldn't know a reflected polynomial is being passed.
The routines for a normal polynomial and a reflected polynomial are entirely different.
aCrc() will handle both. It decides the routine based on the bits (width) parameter.
What does "reflected" mean?
If you write down the bits of a number in a paper and see its refection in a mirror, the bits will be reversed.
In same manner, the polynomial 0x8005 should be reversed to 0xA001
0x8005
= 1000 0000 0000 0101
Reflected:
1010 0000 0000 0001
= 0xA001
We may do it with Reflect() function.
= 1000 0000 0000 0101
Reflected:
1010 0000 0000 0001
= 0xA001
Code: Select all
poly := 0x8005
width := 16
MsgBox % refpoly := Reflect(poly, width) ; 0xA001
Reflect(n, bits) {
Local x:=0
Loop %Bits%
x := (x<<1) | (n&1), n>>= 1
Return Format("0x{:X}", x)
}
Code: Select all
MsgBox % aCrc("AutoHotkey", 0xA001, 0, 0x0000, 0x0000) ; 0x4DCB
The routines for a normal polynomial and a reflected polynomial are entirely different.
aCrc() will handle both. It decides the routine based on the bits (width) parameter.
Parameter presets:
I have pre-computed the required parameters for most of them
and here follows a list of preset objects. For convenience sake, we may refer them as constants.
Code: Select all
CRC_8_AUTOSAR := [0x2f, 8, 0xff, 0xff] ; CRC-8/AUTOSAR
CRC_8_BLUETOOTH := [0xe5, 0, 0x00, 0x00] ; CRC-8/BLUETOOTH
CRC_8_CDMA2000 := [0x9b, 8, 0xff, 0x00] ; CRC-8/CDMA2000
CRC_8_DARC := [0x9c, 0, 0x00, 0x00] ; CRC-8/DARC
CRC_8_DVB_S2 := [0xd5, 8, 0x00, 0x00] ; CRC-8/DVB-S2
CRC_8_GSM_A := [0x1d, 8, 0x00, 0x00] ; CRC-8/GSM-A
CRC_8_GSM_B := [0x49, 8, 0x00, 0xff] ; CRC-8/GSM-B
CRC_8_I_432_1 := [0x07, 8, 0x00, 0x55] ; CRC-8/I-432-1
CRC_8_ITU := [0x07, 8, 0x00, 0x55] ; CRC-8/ITU
CRC_8_I_CODE := [0x1d, 8, 0xfd, 0x00] ; CRC-8/I-CODE
CRC_8_LTE := [0x9b, 8, 0x00, 0x00] ; CRC-8/LTE
CRC_8_MAXIM_DOW := [0x8c, 0, 0x00, 0x00] ; CRC-8/MAXIM-DOW
CRC_8_MAXIM := [0x8c, 0, 0x00, 0x00] ; CRC-8/MAXIM
CRC_8_DOW_CRC := [0x8c, 0, 0x00, 0x00] ; DOW-CRC
CRC_8_MIFARE_MAD := [0x1d, 8, 0xc7, 0x00] ; CRC-8/MIFARE-MAD
CRC_8_NRSC_5 := [0x31, 8, 0xff, 0x00] ; CRC-8/NRSC-5
CRC_8_OPENSAFETY := [0x2f, 8, 0x00, 0x00] ; CRC-8/OPENSAFETY
CRC_8_ROHC := [0xe0, 0, 0xff, 0x00] ; CRC-8/ROHC
CRC_8_SAE_J1850 := [0x1d, 8, 0xff, 0xff] ; CRC-8/SAE-J1850
CRC_8_SMBUS := [0x07, 8, 0x00, 0x00] ; CRC-8/SMBUS
CRC_8 := [0x07, 8, 0x00, 0x00] ; CRC-8
CRC_8_TECH_3250 := [0xb8, 0, 0xff, 0x00] ; CRC-8/TECH-3250
CRC_8_AES := [0xb8, 0, 0xff, 0x00] ; CRC-8/AES
CRC_8_EBU := [0xb8, 0, 0xff, 0x00] ; CRC-8/EBU
CRC_8_WCDMA := [0xd9, 0, 0x00, 0x00] ; CRC-8/WCDMA
CRC_10_ATM := [0x233, 10, 0x000, 0x000] ; CRC-10/ATM
CRC_10 := [0x233, 10, 0x000, 0x000] ; CRC-10
CRC_10_I_610 := [0x233, 10, 0x000, 0x000] ; CRC-10/I-610
CRC_10_CDMA2000 := [0x3d9, 10, 0x3ff, 0x000] ; CRC-10/CDMA2000
CRC_10_GSM := [0x175, 10, 0x000, 0x3ff] ; CRC-10/GSM
CRC_11_FLEXRAY := [0x385, 11, 0x01a, 0x000] ; CRC-11/FLEXRAY
CRC_11 := [0x385, 11, 0x01a, 0x000] ; CRC-11
CRC_11_UMTS := [0x307, 11, 0x000, 0x000] ; CRC-11/UMTS
CRC_12_CDMA2000 := [0xf13, 12, 0xfff, 0x000] ; CRC-12/CDMA2000
CRC_12_DECT := [0x80f, 12, 0x000, 0x000] ; CRC-12/DECT
X_CRC_12 := [0x80f, 12, 0x000, 0x000] ; X-CRC-12
CRC_12_GSM := [0xd31, 12, 0x000, 0xfff] ; CRC-12/GSM
CRC_12_UMTS := [0x80f, 12, 0x000, 0x000] ; CRC-12/UMTS
CRC_12_3GPP := [0x80f, 12, 0x000, 0x000] ; CRC-12/3GPP
CRC_13_BBC := [0x1cf5, 13, 0x0000, 0x0000] ; CRC-13/BBC
CRC_14_DARC := [0x2804, 0, 0x0000, 0x0000] ; CRC-14/DARC
CRC_14_GSM := [0x202d, 14, 0x0000, 0x3fff] ; CRC-14/GSM
CRC_15_CAN := [0x4599, 15, 0x0000, 0x0000] ; CRC-15/CAN
CRC_15 := [0x4599, 15, 0x0000, 0x0000] ; CRC-15
CRC_15_MPT1327 := [0x6815, 15, 0x0000, 0x0001] ; CRC-15/MPT1327
CRC_16_ARC := [0xa001, 0, 0x0000, 0x0000] ; CRC-16/ARC
CRC_16 := [0xa001, 0, 0x0000, 0x0000] ; CRC-16
CRC_16_LHA := [0xa001, 0, 0x0000, 0x0000] ; CRC-16/LHA
CRC_IBM := [0xa001, 0, 0x0000, 0x0000] ; CRC-IBM
CRC_16_CDMA2000 := [0xc867, 16, 0xffff, 0x0000] ; CRC-16/CDMA2000
CRC_16_CMS := [0x8005, 16, 0xffff, 0x0000] ; CRC-16/CMS
CRC_16_DDS_110 := [0x8005, 16, 0x800d, 0x0000] ; CRC-16/DDS-110
CRC_16_DECT_R := [0x0589, 16, 0x0000, 0x0001] ; CRC-16/DECT-R
R_CRC_16 := [0x0589, 16, 0x0000, 0x0001] ; R-CRC-16
CRC_16_DECT_X := [0x0589, 16, 0x0000, 0x0000] ; CRC-16/DECT-X
X_CRC_16 := [0x0589, 16, 0x0000, 0x0000] ; X-CRC-16
CRC_16_DNP := [0xa6bc, 0, 0x0000, 0xffff] ; CRC-16/DNP
CRC_16_EN_13757 := [0x3d65, 16, 0x0000, 0xffff] ; CRC-16/EN-13757
CRC_16_GENIBUS := [0x1021, 16, 0xffff, 0xffff] ; CRC-16/GENIBUS
CRC_16_DARC := [0x1021, 16, 0xffff, 0xffff] ; CRC-16/DARC
CRC_16_EPC := [0x1021, 16, 0xffff, 0xffff] ; CRC-16/EPC
CRC_16_EPC_C1G2 := [0x1021, 16, 0xffff, 0xffff] ; CRC-16/EPC-C1G2
CRC_16_I_CODE := [0x1021, 16, 0xffff, 0xffff] ; CRC-16/I-CODE
CRC_16_GSM := [0x1021, 16, 0x0000, 0xffff] ; CRC-16/GSM
CRC_16_IBM_3740 := [0x1021, 16, 0xffff, 0x0000] ; CRC-16/IBM-3740
CRC_16_AUTOSAR := [0x1021, 16, 0xffff, 0x0000] ; CRC-16/AUTOSAR
CRC_16_CCITT_FALSE := [0x1021, 16, 0xffff, 0x0000] ; CRC-16/CCITT-FALSE
CRC_16_IBM_SDLC := [0x8408, 0, 0xffff, 0xffff] ; CRC-16/IBM-SDLC
CRC_16_ISO_HDLC := [0x8408, 0, 0xffff, 0xffff] ; CRC-16/ISO-HDLC
CRC_16_ISO_IEC_14443_3_B := [0x8408, 0, 0xffff, 0xffff] ; CRC-16/ISO-IEC-14443-3-B
CRC_16_X_25 := [0x8408, 0, 0xffff, 0xffff] ; CRC-16/X-25
CRC_16_CRC_B := [0x8408, 0, 0xffff, 0xffff] ; CRC-B
CRC_16_X_25 := [0x8408, 0, 0xffff, 0xffff] ; X-25
CRC_16_ISO_IEC_14443_3_A := [0x8408, 0, 0xc6c6, 0x0000] ; CRC-16/ISO-IEC-14443-3-A
CRC_16_CRC_A := [0x8408, 0, 0xc6c6, 0x0000] ; CRC-A
CRC_16_KERMIT := [0x8408, 0, 0x0000, 0x0000] ; CRC-16/KERMIT
CRC_16_CCITT := [0x8408, 0, 0x0000, 0x0000] ; CRC-16/CCITT
CRC_16_CCITT_TRUE := [0x8408, 0, 0x0000, 0x0000] ; CRC-16/CCITT-TRUE
CRC_16_V_41_LSB := [0x8408, 0, 0x0000, 0x0000] ; CRC-16/V-41-LSB
CRC_16_LJ1200 := [0x6f63, 16, 0x0000, 0x0000] ; CRC-16/LJ1200
CRC_16_MAXIM_DOW := [0xa001, 0, 0x0000, 0xffff] ; CRC-16/MAXIM-DOW
CRC_16_MAXIM := [0xa001, 0, 0x0000, 0xffff] ; CRC-16/MAXIM
CRC_16_MCRF4XX := [0x8408, 0, 0xffff, 0x0000] ; CRC-16/MCRF4XX
CRC_16_MODBUS := [0xa001, 0, 0xffff, 0x0000] ; CRC-16/MODBUS
CRC_16_NRSC_5 := [0xd010, 0, 0xffff, 0x0000] ; CRC-16/NRSC-5
CRC_16_OPENSAFETY_A := [0x5935, 16, 0x0000, 0x0000] ; CRC-16/OPENSAFETY-A
CRC_16_OPENSAFETY_B := [0x755b, 16, 0x0000, 0x0000] ; CRC-16/OPENSAFETY-B
CRC_16_PROFIBUS := [0x1dcf, 16, 0xffff, 0xffff] ; CRC-16/PROFIBUS
CRC_16_IEC_61158_2 := [0x1dcf, 16, 0xffff, 0xffff] ; CRC-16/IEC-61158-2
CRC_16_RIELLO := [0x8408, 0, 0xb2aa, 0x0000] ; CRC-16/RIELLO
CRC_16_SPI_FUJITSU := [0x1021, 16, 0x1d0f, 0x0000] ; CRC-16/SPI-FUJITSU
CRC_16_AUG_CCITT := [0x1021, 16, 0x1d0f, 0x0000] ; CRC-16/AUG-CCITT
CRC_16_T10_DIF := [0x8bb7, 16, 0x0000, 0x0000] ; CRC-16/T10-DIF
CRC_16_TELEDISK := [0xa097, 16, 0x0000, 0x0000] ; CRC-16/TELEDISK
CRC_16_TMS37157 := [0x8408, 0, 0x89ec, 0x0000] ; CRC-16/TMS37157
CRC_16_UMTS := [0x8005, 16, 0x0000, 0x0000] ; CRC-16/UMTS
CRC_16_BUYPASS := [0x8005, 16, 0x0000, 0x0000] ; CRC-16/BUYPASS
CRC_16_VERIFONE := [0x8005, 16, 0x0000, 0x0000] ; CRC-16/VERIFONE
CRC_16_USB := [0xa001, 0, 0xffff, 0xffff] ; CRC-16/USB
CRC_16_XMODEM := [0x1021, 16, 0x0000, 0x0000] ; CRC-16/XMODEM
CRC_16_ZMODEM := [0x1021, 16, 0x0000, 0x0000] ; CRC-16/ZMODEM
CRC_16_ACORN := [0x1021, 16, 0x0000, 0x0000] ; CRC-16/ACORN
CRC_16_LTE := [0x1021, 16, 0x0000, 0x0000] ; CRC-16/LTE
CRC_16_V_41_MSB := [0x1021, 16, 0x0000, 0x0000] ; CRC-16/V-41-MSB
CRC_17_CAN_FD := [0x1685b, 17, 0x00000, 0x00000] ; CRC-17/CAN-FD
CRC_21_CAN_FD := [0x102899, 21, 0x000000, 0x000000] ; CRC-21/CAN-FD
CRC_24_BLE := [0xda6000, 0, 0x555555, 0x000000] ; CRC-24/BLE
CRC_24_FLEXRAY_A := [0x5d6dcb, 24, 0xfedcba, 0x000000] ; CRC-24/FLEXRAY-A
CRC_24_FLEXRAY_B := [0x5d6dcb, 24, 0xabcdef, 0x000000] ; CRC-24/FLEXRAY-B
CRC_24_INTERLAKEN := [0x328b63, 24, 0xffffff, 0xffffff] ; CRC-24/INTERLAKEN
CRC_24_LTE_A := [0x864cfb, 24, 0x000000, 0x000000] ; CRC-24/LTE-A
CRC_24_LTE_B := [0x800063, 24, 0x000000, 0x000000] ; CRC-24/LTE-B
CRC_24_OPENPGP := [0x864cfb, 24, 0xb704ce, 0x000000] ; CRC-24/OPENPGP
CRC_24 := [0x864cfb, 24, 0xb704ce, 0x000000] ; CRC-24
CRC_24_OS_9 := [0x800063, 24, 0xffffff, 0xffffff] ; CRC-24/OS-9
CRC_30_CDMA := [0x2030b9c7, 30, 0x3fffffff, 0x3fffffff] ; CRC-30/CDMA
CRC_31_PHILIPS := [0x04c11db7, 31, 0x7fffffff, 0x7fffffff] ; CRC-31/PHILIPS
CRC_32_AIXM := [0x814141ab, 32, 0x00000000, 0x00000000] ; CRC-32/AIXM
CRC_32Q := [0x814141ab, 32, 0x00000000, 0x00000000] ; CRC-32Q
CRC_32_AUTOSAR := [0xc8df352f, 0, 0xffffffff, 0xffffffff] ; CRC-32/AUTOSAR
CRC_32_BASE91_D := [0xd419cc15, 0, 0xffffffff, 0xffffffff] ; CRC-32/BASE91-D
CRC_32D := [0xd419cc15, 0, 0xffffffff, 0xffffffff] ; CRC-32D
CRC_32_BZIP2 := [0x04c11db7, 32, 0xffffffff, 0xffffffff] ; CRC-32/BZIP2
CRC_32_AAL5 := [0x04c11db7, 32, 0xffffffff, 0xffffffff] ; CRC-32/AAL5
CRC_32_DECT_B := [0x04c11db7, 32, 0xffffffff, 0xffffffff] ; CRC-32/DECT-B
B_CRC_32 := [0x04c11db7, 32, 0xffffffff, 0xffffffff] ; B-CRC-32
CRC_32_CD_ROM_EDC := [0xd8018001, 0, 0x00000000, 0x00000000] ; CRC-32/CD-ROM-EDC
CRC_32_CKSUM := [0x04c11db7, 32, 0x00000000, 0xffffffff] ; CRC-32/CKSUM
CRC_32_POSIX := [0x04c11db7, 32, 0x00000000, 0xffffffff] ; CRC-32/POSIX
CRC_32_ISCSI := [0x82f63b78, 0, 0xffffffff, 0xffffffff] ; CRC-32/ISCSI
CRC_32_BASE91_C := [0x82f63b78, 0, 0xffffffff, 0xffffffff] ; CRC-32/BASE91-C
CRC_32_CASTAGNOLI := [0x82f63b78, 0, 0xffffffff, 0xffffffff] ; CRC-32/CASTAGNOLI
CRC_32_INTERLAKEN := [0x82f63b78, 0, 0xffffffff, 0xffffffff] ; CRC-32/INTERLAKEN
CRC_32C := [0x82f63b78, 0, 0xffffffff, 0xffffffff] ; CRC-32C
CRC_32_ISO_HDLC := [0xedb88320, 0, 0xffffffff, 0xffffffff] ; CRC-32/ISO-HDLC
CRC_32 := [0xedb88320, 0, 0xffffffff, 0xffffffff] ; CRC-32
CRC_32_ADCCP := [0xedb88320, 0, 0xffffffff, 0xffffffff] ; CRC-32/ADCCP
CRC_32_V_42 := [0xedb88320, 0, 0xffffffff, 0xffffffff] ; CRC-32/V-42
CRC_32_XZ := [0xedb88320, 0, 0xffffffff, 0xffffffff] ; CRC-32/XZ
CRC_32_PKZIP := [0xedb88320, 0, 0xffffffff, 0xffffffff] ; PKZIP
CRC_32_JAMCRC := [0xedb88320, 0, 0xffffffff, 0x00000000] ; CRC-32/JAMCRC
CRC_32_MPEG_2 := [0x04c11db7, 32, 0xffffffff, 0x00000000] ; CRC-32/MPEG-2
CRC_32_XFER := [0x000000af, 32, 0x00000000, 0x00000000] ; CRC-32/XFER
CRC_40_GSM := [0x0004820009, 40, 0x0000000000, 0xffffffffff] ; CRC-40/GSM
Code: Select all
CRC_16_CCITT_FALSE := [0x1021, 16, 0xffff, 0x0000] ; CRC-16/CCITT-FALSE
CRC_32 := [0xedb88320, 0, 0xffffffff, 0xffffffff] ; CRC-32
MsgBox % aCrc("AutoHotkey", CRC_16_CCITT_FALSE*) ; 0x45EB
MsgBox % aCrc("AutoHotkey", CRC_32*) ; 0x14C70CF9
The function:
Code: Select all
aCrc( sStr, Poly, Bits, Init, XorOut ) { ; aCrc() v0.24 by SKAN on D449/D44F @ tiny.cc/acrc
Local D:=Poly+0, R:=Init, Bin:="", pPtr:=0, S:=0, T:=0
VarSetCapacity(Bin, n:=StrPut(sStr, "utf-8") -1)
, StrPut(sStr, pPtr := &Bin, n, "utf-8")
If ( Bits )
Loop % ( n, S := Bits-8, T := 1<<Bits-1 )
R ^= NumGet(pPtr+0, A_Index-1, "UChar") << S
, R := (R & T) ? ( (R << 1) ^ D ) : (R << 1), R := (R & T) ? ( (R << 1) ^ D ) : (R << 1)
, R := (R & T) ? ( (R << 1) ^ D ) : (R << 1), R := (R & T) ? ( (R << 1) ^ D ) : (R << 1)
, R := (R & T) ? ( (R << 1) ^ D ) : (R << 1), R := (R & T) ? ( (R << 1) ^ D ) : (R << 1)
, R := (R & T) ? ( (R << 1) ^ D ) : (R << 1), R := (R & T) ? ( (R << 1) ^ D ) : (R << 1)
Else
Loop % ( n )
R ^= NumGet(pPtr+0, A_Index-1, "UChar")
, R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1), R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1)
, R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1), R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1)
, R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1), R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1)
, R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1), R := (R & 1) ? ( (R >> 1) ^ D ) : (R >> 1)
Return Bits ? Format("0x{:X}", (R & (2**Bits-1)) ^ XorOut) : Format("0x{:X}", R ^ XorOut)
}