This was originally called a Fletcher's Checksum after the creator. I agree it is a nice checksum, I've been using this to checksum things since the mid 80's! It's well documented in a back issue of Dr Dobb's journal, you could probably find it on their site, or at least in their back issue CD. FWIW: It's only "very close" to a CRC in security on blocks below 255 bytes, it's comparison to CRC falls off quickly after that. But for small packets it's very good! And for anything larger it's a heck of a lot better than a standard checksum. -Zonn On Thu, 9 May 2002 00:34:24 +0100, "Phillip Eaton" <inbox@phillipeaton.com> wrote:
For those interested, here's another checksum algorithm designed by BT in the UK, called a Frame Check Sequence number (FCS).
It's not quite as secure as a CRC, but it is very close and it is much, much easier to calculate. (You can make out the algorithm from the code).
I implemented it in Z80 assembly using a Forth cross-compiler (i.e. it's all backwards) for some embedded stuff I was working on.
A CRC on the other hand, is much harder to calculate. See the comparable listing at the end. It also shows my start value as 8408.
I'm a bit confused myself now, actually, as the CRC code seems to process the whole 16 bit old CRC in one go (or at least it would if the Z80 was a true 16 bit processor), which is a bit different from running 1 bit at a time. I'll hae to do some testing...when I get some time!
Phil.
\ -------------------------------------------------------------------------- - \ FCS \ \ Descripton: Piece of Z80/H64180 code to implement the FCS algorithm as \ defined by British Telecom New Networks Technical Forum - \ Document CP(83)/12 04/02/83. Call with the old FCS and data \ byte to be FCS'd and a new FCS is returned. Note the 'exx' \ at the start and end of the code - MPE Z80 forth crashes if \ you use the standard BC registers. You should be able to \ remove these if you are using any other compiler. \ To parse a complete buffer of information, you need an \ external loop which calls this function for each data byte. \ FCS = File Check Sequence \ \ Parameters: fcs_c0c1 - Old FCS to modify. \ char - Value to add to FCS. \ \ Returns: new_fcs_c0c1 - New FCS. \ \ -------------------------------------------------------------------------- -
Code FCS \ fcs_c0c1 char --- new_fcs_c0c1 ;
EXX
BC POP \ Contains new data byte in C DE POP \ Contains old FCS, D=c0, E=c1
A, D LD \ Calc new c0, c0=c0+char A, C ADD NC, fcs1 JP \ If result > $ff then A INC \ add 1 to result L: fcs1 D, A LD \ Store back to c0
A, E LD \ Calc new c1, c1=c1+c0 A, D ADD NC, fcs2 JP \ If result > $ff then A INC \ add 1 to result L: fcs2 E, A LD \ Store back to c1
DE PUSH
EXX NEXT,
End-Code
************ CRC CODE STARTS HERE *********** HEX
$8408 equ CRC-Seed \ Good initial value for CRC calculation.
Code CRC-16 \ crc char --- new_crc ;
EXX
BC POP \ Contains new data byte in C DE POP \ Contains old CRC HL, # 0 LD \ Define Work Area
A, E LD \ XOR bottom 8 bits of old CRC with data byte A, C XOR E, A LD
A, H LD \ Swap bottom 8 bits of CRC with top 8 bits of H, E LD \ Work Area E, A LD
A, D LD \ Swap top 8 bits of CRC with bottom 8 bits D, E LD E, A LD
PE, L1 JP \ If parity of XOR even, miss out the CRC XOR
A, D LD \ XOR the CRC with C001H A, # C0 XOR D, A LD
A, E LD A, # 01 XOR E, A LD
L: L1
SCF \ Right shift the CRC and then XOR it with work area CCF
H RR L RR
A, D LD A, H XOR D, A LD
A, E LD A, L XOR E, A LD
SCF \ Right shift the CRC and then XOR it with work area CCF \ again
H RR L RR
A, D LD A, H XOR D, A LD
A, E LD A, L XOR E, A LD
DE PUSH \ Shove the new CRC back on the stack
EXX NEXT,
End-code