Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Checksum

266 views
Skip to first unread message

Jeff Waite

unread,
Mar 2, 2006, 3:30:27 PM3/2/06
to
What is the best way to compute a 16-bit checksum in TCL? I've tried
using the cksum() and crc::sum commands but I just receive the error
"invalid command name."

Here's my code:

set data
\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
LogToScreen "Checksum: cksum"
set cks [cksum($data)]
LogToScreen $cks
LogToScreen "Checksum: crc::sum"
set crcsum [crc::sum -format 0x%X $data]
LogToScreen $crcsum

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

1111 0101 0100 1110

4. Convert back to hex

F54E

5. Show low byte first and then high byte

4EF5

Checksum = 4EF5

Uwe Klein

unread,
Mar 2, 2006, 3:54:20 PM3/2/06
to
Hi,
> set cks [cksum($data)]

don't do that tcl is not C

what about:

% package require crc16
% set data


"\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"

% ::crc::crc16 $data
6800

G!
uwe

Bryan Oakley

unread,
Mar 2, 2006, 3:59:23 PM3/2/06
to
Jeff Waite wrote:
> What is the best way to compute a 16-bit checksum in TCL? I've tried
> using the cksum() and crc::sum commands but I just receive the error
> "invalid command name."
>
> Here's my code:
>
> set data
> \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
> LogToScreen "Checksum: cksum"
> set cks [cksum($data)]

Unless you've stored the name of the command in an array named cksum,
that should probably be:

set cks [crc::cksum $data]

You might need to add "package require cksum" to your code as well. It's
unfortunate that you need to do "package require cksum" but the commands
actually live in the crc namespace.

Out of curiosity, what's the point of this exercise? Is it homework?

Message has been deleted
Message has been deleted

Jeff Waite

unread,
Mar 2, 2006, 5:29:49 PM3/2/06
to
I'm a newbie to TCL. When I add the command "package require cksum",
I get the error "can't find package cksum." Is there a file I should
add to the server? If so, do you know where I can download it?

I'm trying to get a network operations software package called Priisms
to display alarm messages on an LED marquee. The command to change
the text on the sign is a series of hex numbers with a 16-bit checksum
at the end.

Uwe Klein

unread,
Mar 3, 2006, 4:06:46 AM3/3/06
to
Jeff Waite wrote:
> I'm a newbie to TCL. When I add the command "package require cksum",
> I get the error "can't find package cksum." Is there a file I should

you need the "crc16" package which is a part of tcllib
( there is also a crc32 and some other crc types )
as in :

package require crc16

assumed the chars to chksumm are in the variable "data"

the command to generate crc16 is

set chksum [ ::crc::crc16 $data ]

see my previous post

uwe

Jeff Waite

unread,
Mar 8, 2006, 6:06:03 PM3/8/06
to
I tried that but I get the error "can't find package crc16"

What is the procedure for adding the crc16 library to TCL?

Jeff Waite

unread,
Mar 8, 2006, 8:47:42 PM3/8/06
to
Just FYI, I figured out how to add the package with some help from a
colleague. The command was:

source "d:/priisms/crc16.tcl"

Jeff Waite

unread,
Mar 15, 2006, 7:29:15 PM3/15/06
to
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. 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:

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

Paul Whitfield

unread,
Mar 15, 2006, 10:24:19 PM3/15/06
to

Here is my attempt, the numbers don't work out the
same as your example... but I think what I have done
is correct.

Please note: your problem description was not very precise:
"Sum up all the numbers" is not a complete description,
a better description would be "16 bits sum of each BYTE"

set data
"\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"

proc checksum data {
set sum 0
for { set i 0 } { $i < [ string length $data ] } { incr i } {
binary scan $data "@${i}c" int

incr sum $int
puts "[format "%x, %x" $sum $int ]"
}
puts "[format %x $sum]"
set sum [ expr { ( (~$sum << 8 ) & 0xff00 ) | (( ~$sum >> 8 ) &
0x00ff ) } ]
return $sum
}

puts "Checksum is [ format %x [ checksum $data ] ]"


And the output is

set data
"\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"

proc checksum data {
set sum 0
for { set i 0 } { $i < [ string length $data ] } { incr i } {
binary scan $data "@${i}c" int

incr sum $int
puts "[format "%x, %x" $sum $int ]"
}
puts "[format %x $sum]"
set sum [ expr { ( (~$sum << 8 ) & 0xff00 ) | (( ~$sum >> 8 ) &
0x00ff ) } ]
return $sum
}


puts "Checksum is [ format %x [ checksum $data ] ]"


Regards

Paul

Message has been deleted

Paul Whitfield

unread,
Mar 15, 2006, 10:42:39 PM3/15/06
to

Here is my attempt, the numbers don't work out the


same as your example... but I think what I have done
is correct.

Please note: your problem description was not very precise:
"Sum up all the numbers" is not a complete description,
a better description would be

"Add the value of each 8-bit value to a 16 bit sum"

set data
"\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"

proc checksum data {


set sum 0
for { set i 0 } { $i < [ string length $data ] } { incr i } {
binary scan $data "@${i}c" int

incr sum $int
puts "[format "%x, %x" $sum $int ]"
}
puts "[format %x $sum]"
set sum [ expr { ( (~$sum << 8 ) & 0xff00 ) | (( ~$sum >> 8 ) &
0x00ff ) } ]
return $sum
}

puts "Checksum is [ format %x [ checksum $data ] ]"


And the output is

0, 0
4d, 4d
8e, 41
d7, 49
125, 4e
125, 0
125, 0
125, 0
125, 0
14b, 26
14b, 0
14f, 4
154, 5
163, f
16c, 9
16d, 1
173, 6
162, ffffffef
154, fffffff2
155, 1
147, fffffff2
13a, fffffff3
13b, 1
12e, fffffff3
182, 54
1e7, 65
25a, 73
2ce, 74
337, 69
3a5, 6e
40c, 67
42c, 20
45d, 31
48f, 32
4c2, 33
4b1, ffffffef
4b1
Checksum is 4efb


Regards

Paul

Gerald W. Lester

unread,
Mar 16, 2006, 2:01:35 AM3/16/06
to
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)?

--
+--------------------------------+---------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

Paul Whitfield

unread,
Mar 16, 2006, 3:03:21 AM3/16/06
to
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.
* simple communication protocols that use a simple "check sum" like
this. Often in embedded processors with limited processing power/resources.

The bad thing about such algorithms is that they are not that
good at detecting anything other than a single bit error.

Regards

Paul

Paul Whitfield

unread,
Mar 16, 2006, 3:16:31 AM3/16/06
to

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


Gerald W. Lester

unread,
Mar 16, 2006, 8:46:05 AM3/16/06
to
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.

Uwe Klein

unread,
Mar 16, 2006, 9:28:23 AM3/16/06
to
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

Donal K. Fellows

unread,
Mar 16, 2006, 10:39:10 AM3/16/06
to
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.

Jeff Waite

unread,
Mar 16, 2006, 3:16:14 PM3/16/06
to

That works. Thanks for your help.

Jeff

0 new messages