Prev: launching wish from tclsh
Next: tcl/tk on Windows: "This application has requested the Runtime to terminate it in an unusual way" on quit
From: Gerald W. Lester on 16 Mar 2006 08:46 Paul Whitfield wrote: > Gerald W. Lester wrote: >> Jeff Waite wrote: >>> I'm still having a problem with creating a 16-bit checksum. I've >>> tried using cksum, sum, and crc but they all produce values that are >>> significantly different than what I need. I suppose they may be >>> computing the checksum differently. >> >> Yes they each have their documented algorithms -- and none of them >> match the one you (rather imprecisely describe below). >> >>> Below is an example of how I need >>> to compute the checksum. >>> >>> I suspect that I'm going to have to build my own algorithm. Does >>> anyone know which TCL commands I can use to do the following: >> >> Sure: expr, binary scan, foreach, string range, format, set, and maybe >> proc and return. > > <SNIP> Worked example removed </SNIP> > >> BTW, this is a rather strange algorithm would you care to share >> what/where it is being used (just to satisfy my curiosity)? > > Examples where I have seen this "type" of checksum include: > > * motorola S-record file, that is an ASCII file format that is used for > storing binary file. Ok, did not know about that one. > * simple communication protocols that use a simple "check sum" like > this. Often in embedded processors with limited processing power/resources. I have not seen a check sum like this used since the `70s -- I thought everyone had either switched over to CRC-32 of dropped check sums since they were running their protocol on top of Tcp/IP. Sorry for the typo you pointed out in your other message -- cut, paste and clean up error that happened late at night. -- +--------------------------------+---------------------------------------+ | Gerald W. Lester | |"The man who fights for his ideals is the man who is alive." - Cervantes| +------------------------------------------------------------------------+
From: Uwe Klein on 16 Mar 2006 09:28 Gerald W. Lester wrote: > I have not seen a check sum like this used since the `70s -- I thought > everyone had either switched over to CRC-32 of dropped check sums since > they were running their protocol on top of Tcp/IP. you will find 8bit checksums in Intel HEX type files. > http://www.cs.net/lucid/intel.htm jedec fusemaps have 16Bit but on the asciis not the bytevalues: > The transmission checksum is the 16 bit sum (that is, modulo 65,535) of all > ASCII characters transmitted between and including the STX and ETX. The > parity bit is excluded in the calculation. there is some format were the chksum is not modulo something instead the overflow is folded into chksumlength i.e. set chksum [ expr [ join $bytes + ] ] while {$chksum > 0x0ffff } { set chksum [ expr ( $chksum & 0x0ffff ) + ( $chksum >>16 ) ] } uwe
From: Donal K. Fellows on 16 Mar 2006 10:39 Gerald W. Lester wrote: > I have not seen a check sum like this used since the `70s -- I thought > everyone had either switched over to CRC-32 of dropped check sums since > they were running their protocol on top of Tcp/IP. FWIW, important stuff actually uses either: 1) error-correcting codes instead of checksums, so that minor errors are restored automatically, or 2) cryptographic hashes, so that even malicious changes are impractical Donal.
From: Jeff Waite on 16 Mar 2006 15:16
That works. Thanks for your help. Jeff Paul Whitfield wrote: > Gerald W. Lester wrote: > > Jeff Waite wrote: > >> I'm still having a problem with creating a 16-bit checksum. I've > >> tried using cksum, sum, and crc but they all produce values that are > >> significantly different than what I need. I suppose they may be > >> computing the checksum differently. > > > > Yes they each have their documented algorithms -- and none of them match > > the one you (rather imprecisely describe below). > > > >> Below is an example of how I need > >> to compute the checksum. > >> > >> I suspect that I'm going to have to build my own algorithm. Does > >> anyone know which TCL commands I can use to do the following: > > > > Sure: expr, binary scan, foreach, string range, format, set, and maybe > > proc and return. > > > >> > >> 1. Sum a series of hex numbers > >> 2. Perform a bit flip (binary complement) > >> > >> FYI, I'm trying to create a checksum for a series of hex numbers. For > >> example: > >> > >> Input: > >> > >> \x00\x4d\x41\x49\x4e\x00\x00\x00\x00\x26\x00\x04\x05\x0f\x09\x01\x06\xef\xf2\x01\xf2\xf3\x01\xf3\x54\x65\x73\x74\x69\x6e\x67\x20\x31\x32\x33\xef > >> > >> > >> 1. Sum up all the numbers > >> > >> Sum = 0AB1 > >> > >> 2. Convert to binary > >> > >> 0000 1010 1011 0001 > >> > >> 3. Take the complement (bit flip) > >> > >> 1111 0101 0100 1110 > >> > >> 4. Convert back to hex > >> > >> F54E > >> > >> 5. Show low byte first and then high byte > >> > >> 4EF5 > >> > >> Checksum = 4EF5 > >> > > > > Try: > > proc checksum {str} { > > binary scan $str c* byteList > > set sum 0 > > foreach bye $byteList { > > set sum [expr {($sum + $bye & 0xff}) & 0xffff}] > > } > > set sumStr [format {%4.4x} [expr {~$sum & 0xffff}]] > > return [string range $sumStr 2 3][string range $sumStr 0 1] > > } > > > > BTW, this is a rather strange algorithm would you care to share > > what/where it is being used (just to satisfy my curiosity)? > > There is a typo in this example, the bracing in the expr are wrong > and it does not give the correct result.. BUT > > ...it made me see the mistake in my earlier attempt, I needed to > force the bytes to be unsigned by masking with 0xff: > > Here is a fixed version of my code that give the correct result, > using a better scan format cribbed from Gerald ... > > proc checksum data { > set sum 0 > binary scan $data "c*" bytes > foreach int $bytes { > set sum [ expr { $sum + ( $int & 0xff ) } ] > } > set sum [ expr { ( (~$sum << 8 ) & 0xff00 ) | (( ~$sum >> 8 ) & > 0x00ff) } ] > return $sum > } > > Hope that helps > > Paul |