Menu

#1161 signmask incorrect in ::crc::Crc and ::crc::Crc32_tcl

open
crc (13)
9
2009-09-01
2009-09-01
No

Both crc16.tcl and crc32.tcl use a variable named "signmask", that is constructed from another variable named "signbit".

For 32-bit data, signbit is 0x8000000.

For 32-bit CRCs, the signmask appears to be designed to mask off the high-byte, i.e. it should end up 0x00ffffff. Signmask is computed as follows:

set signmask [expr {~$signbit>>7}]

Unfortunately when you paste this code into Tcl, (V8.4.14, V8.5.*, V8.6.*) you don't get 0x00FFFFFF, you get 0xFEFFFFFF.

Now, this is *probably* a bug in EXPR or in the >> operator, but the code does not work the way it is currently written....

Discussion

  • Karl C. Hansen

    Karl C. Hansen - 2009-09-01

    Posted this as potential bug to TCL sourceforge:

    ID:
    #2848176
    Link:
    https://sourceforge.net/tracker/?func=detail&aid=2848176&group_id=10894&atid=110894

    Response is that since V8.2 this is designed behavior.

    CRC Tcl implementations need to be rewritten to behave correctly with new wide support.

    If no one has the time let me know and I'll submit a proposed fix.

    I elevated the priority to 9 because the current code generates incorrect 32-bit results with the Tcl implementations.

     
  • Karl C. Hansen

    Karl C. Hansen - 2009-09-01
    • priority: 5 --> 9
     
  • Karl C. Hansen

    Karl C. Hansen - 2009-12-30

    Believe this can be fixed by simply changing the initial value for "v" when originally computing signmask from "1" to "-1":

    Change from:
    for {set v 1} {int($v) != 0} {set signbit $v; set v [expr {$v<<1}]} {}

    To:
    for {set v -1} {int($v) != 0} {set signbit $v; set v [expr {$v<<1}]} {}

    This guarantees that signmask will always be negative and that "~signmask" will always be a non-negative low-order bitmask.