cksum.tcl

Go to the documentation of this file.
00001 /*  cksum.tcl - Copyright (C) 2002 Pat Thoyts <patthoyts@users.sourceforge.net>*/
00002 /* */
00003 /*  Provides a Tcl only implementation of the unix cksum(1) command. This is*/
00004 /*  similar to the sum(1) command but the algorithm is better defined and*/
00005 /*  standardized across multiple platforms by POSIX 1003.2/D11.2*/
00006 /* */
00007 /*  This command has been verified against the cksum command from the GNU*/
00008 /*  textutils package version 2.0*/
00009 /* */
00010 /*  -------------------------------------------------------------------------*/
00011 /*  See the file "license.terms" for information on usage and redistribution*/
00012 /*  of this file, and for a DISCLAIMER OF ALL WARRANTIES.*/
00013 /*  -------------------------------------------------------------------------*/
00014 /*  $Id: cksum.tcl,v 1.9 2006/09/19 23:36:15 andreas_kupries Exp $*/
00015 
00016 package require Tcl 8.2;                /*  tcl minimum version*/
00017 
00018 namespace ::crc {
00019     variable cksum_version 1.1.1
00020 
00021     namespace export cksum
00022 
00023     variable cksum_tbl [list 0x0 \
00024            0x04C11DB7 0x09823B6E 0x0D4326D9 0x130476DC 0x17C56B6B \
00025            0x1A864DB2 0x1E475005 0x2608EDB8 0x22C9F00F 0x2F8AD6D6 \
00026            0x2B4BCB61 0x350C9B64 0x31CD86D3 0x3C8EA00A 0x384FBDBD \
00027            0x4C11DB70 0x48D0C6C7 0x4593E01E 0x4152FDA9 0x5F15ADAC \
00028            0x5BD4B01B 0x569796C2 0x52568B75 0x6A1936C8 0x6ED82B7F \
00029            0x639B0DA6 0x675A1011 0x791D4014 0x7DDC5DA3 0x709F7B7A \
00030            0x745E66CD 0x9823B6E0 0x9CE2AB57 0x91A18D8E 0x95609039 \
00031            0x8B27C03C 0x8FE6DD8B 0x82A5FB52 0x8664E6E5 0xBE2B5B58 \
00032            0xBAEA46EF 0xB7A96036 0xB3687D81 0xAD2F2D84 0xA9EE3033 \
00033            0xA4AD16EA 0xA06C0B5D 0xD4326D90 0xD0F37027 0xDDB056FE \
00034            0xD9714B49 0xC7361B4C 0xC3F706FB 0xCEB42022 0xCA753D95 \
00035            0xF23A8028 0xF6FB9D9F 0xFBB8BB46 0xFF79A6F1 0xE13EF6F4 \
00036            0xE5FFEB43 0xE8BCCD9A 0xEC7DD02D 0x34867077 0x30476DC0 \
00037            0x3D044B19 0x39C556AE 0x278206AB 0x23431B1C 0x2E003DC5 \
00038            0x2AC12072 0x128E9DCF 0x164F8078 0x1B0CA6A1 0x1FCDBB16 \
00039            0x018AEB13 0x054BF6A4 0x0808D07D 0x0CC9CDCA 0x7897AB07 \
00040            0x7C56B6B0 0x71159069 0x75D48DDE 0x6B93DDDB 0x6F52C06C \
00041            0x6211E6B5 0x66D0FB02 0x5E9F46BF 0x5A5E5B08 0x571D7DD1 \
00042            0x53DC6066 0x4D9B3063 0x495A2DD4 0x44190B0D 0x40D816BA \
00043            0xACA5C697 0xA864DB20 0xA527FDF9 0xA1E6E04E 0xBFA1B04B \
00044            0xBB60ADFC 0xB6238B25 0xB2E29692 0x8AAD2B2F 0x8E6C3698 \
00045            0x832F1041 0x87EE0DF6 0x99A95DF3 0x9D684044 0x902B669D \
00046            0x94EA7B2A 0xE0B41DE7 0xE4750050 0xE9362689 0xEDF73B3E \
00047            0xF3B06B3B 0xF771768C 0xFA325055 0xFEF34DE2 0xC6BCF05F \
00048            0xC27DEDE8 0xCF3ECB31 0xCBFFD686 0xD5B88683 0xD1799B34 \
00049            0xDC3ABDED 0xD8FBA05A 0x690CE0EE 0x6DCDFD59 0x608EDB80 \
00050            0x644FC637 0x7A089632 0x7EC98B85 0x738AAD5C 0x774BB0EB \
00051            0x4F040D56 0x4BC510E1 0x46863638 0x42472B8F 0x5C007B8A \
00052            0x58C1663D 0x558240E4 0x51435D53 0x251D3B9E 0x21DC2629 \
00053            0x2C9F00F0 0x285E1D47 0x36194D42 0x32D850F5 0x3F9B762C \
00054            0x3B5A6B9B 0x0315D626 0x07D4CB91 0x0A97ED48 0x0E56F0FF \
00055            0x1011A0FA 0x14D0BD4D 0x19939B94 0x1D528623 0xF12F560E \
00056            0xF5EE4BB9 0xF8AD6D60 0xFC6C70D7 0xE22B20D2 0xE6EA3D65 \
00057            0xEBA91BBC 0xEF68060B 0xD727BBB6 0xD3E6A601 0xDEA580D8 \
00058            0xDA649D6F 0xC423CD6A 0xC0E2D0DD 0xCDA1F604 0xC960EBB3 \
00059            0xBD3E8D7E 0xB9FF90C9 0xB4BCB610 0xB07DABA7 0xAE3AFBA2 \
00060            0xAAFBE615 0xA7B8C0CC 0xA379DD7B 0x9B3660C6 0x9FF77D71 \
00061            0x92B45BA8 0x9675461F 0x8832161A 0x8CF30BAD 0x81B02D74 \
00062            0x857130C3 0x5D8A9099 0x594B8D2E 0x5408ABF7 0x50C9B640 \
00063            0x4E8EE645 0x4A4FFBF2 0x470CDD2B 0x43CDC09C 0x7B827D21 \
00064            0x7F436096 0x7200464F 0x76C15BF8 0x68860BFD 0x6C47164A \
00065            0x61043093 0x65C52D24 0x119B4BE9 0x155A565E 0x18197087 \
00066            0x1CD86D30 0x029F3D35 0x065E2082 0x0B1D065B 0x0FDC1BEC \
00067            0x3793A651 0x3352BBE6 0x3E119D3F 0x3AD08088 0x2497D08D \
00068            0x2056CD3A 0x2D15EBE3 0x29D4F654 0xC5A92679 0xC1683BCE \
00069            0xCC2B1D17 0xC8EA00A0 0xD6AD50A5 0xD26C4D12 0xDF2F6BCB \
00070            0xDBEE767C 0xE3A1CBC1 0xE760D676 0xEA23F0AF 0xEEE2ED18 \
00071            0xF0A5BD1D 0xF464A0AA 0xF9278673 0xFDE69BC4 0x89B8FD09 \
00072            0x8D79E0BE 0x803AC667 0x84FBDBD0 0x9ABC8BD5 0x9E7D9662 \
00073            0x933EB0BB 0x97FFAD0C 0xAFB010B1 0xAB710D06 0xA6322BDF \
00074            0xA2F33668 0xBCB4666D 0xB8757BDA 0xB5365D03 0xB1F740B4 ]
00075 
00076     variable uid ; if {![info exists uid]} { uid =  0}
00077 }
00078 
00079 /*  crc::CksumInit -- */
00080 /* */
00081 /*  Create and initialize a cksum context. This is cleaned up when we*/
00082 /*  call CksumFinal to obtain the result.*/
00083 /* */
00084 ret  ::crc::CksumInit () {
00085     variable uid
00086     set token [namespace current]::[incr uid]
00087     upvar #0 $token state
00088     array set state {t 0 l 0}
00089     return $token
00090 }
00091 
00092 ret  ::crc::CksumUpdate (type token , type data) {
00093     variable cksum_tbl
00094     upvar #0 $token state
00095     set t $state(t)
00096     binary scan $data c* r
00097     foreach {n} $r {
00098         set t [expr {($t << 8)
00099                      ^ [lindex $cksum_tbl [expr {
00100                                                  (($t >> 24) \
00101                                                       ^ ($n & 0xFF)) & 0xFF
00102                                              }]]}]
00103         incr state(l)
00104     }
00105     set state(t) $t
00106     return
00107 }
00108 
00109 ret  ::crc::CksumFinal (type token) {
00110     variable cksum_tbl
00111     upvar #0 $token state
00112     set t $state(t)
00113     for {set i $state(l)} {$i > 0} {set i [expr {$i>>8}]} {
00114         set t [expr {($t << 8) \
00115                          ^ [lindex $cksum_tbl \
00116                                 [expr {(($t >> 24) ^ $i) & 0xFF}]]}]
00117     }
00118     return [expr {~$t & 0xFFFFFFFF}]
00119 }
00120 
00121 /*  crc::Pop --*/
00122 /* */
00123 /*  Pop the nth element off a list. Used in options processing.*/
00124 /* */
00125 ret  ::crc::Pop (type varname , optional nth =0) {
00126     upvar $varname args
00127     set r [lindex $args $nth]
00128     set args [lreplace $args $nth $nth]
00129     return $r
00130 }
00131 
00132 /*  Description:*/
00133 /*   Provide a Tcl equivalent of the unix cksum(1) command.*/
00134 /*  Options:*/
00135 /*   -filename name  - return a checksum for the specified file.*/
00136 /*   -format string  - return the checksum using this format string.*/
00137 /*   -chunksize size - set the chunking read size*/
00138 /* */
00139 ret  ::crc::cksum (type args) {
00140     array set opts [list -filename {} -channel {} -chunksize 4096 \
00141                         -format %u -command {}]
00142     while {[string match -* [set option [lindex $args 0]]]} {
00143         switch -glob -- $option {
00144             -file*   { set opts(-filename) [Pop args 1] }
00145             -chan*   { set opts(-filename) [Pop args 1] }
00146             -chunk*  { set opts(-filename) [Pop args 1] }
00147             -for*    { set opts(-format)   [Pop args 1] }
00148             -command { set opts(-command)  [Pop args 1] }
00149             default {
00150                 if {[llength $args] == 1} { break }
00151                 if {[string compare $option "--"] == 0} { Pop args ; break }
00152                 set err [join [lsort [array names opts -*]] ", "]
00153                 return -code error "bad option \"option\": must be $err"
00154             }
00155         }
00156         Pop args
00157     }
00158 
00159     if {$opts(-filename) != {}} {
00160         set opts(-channel) [open $opts(-filename) r]
00161         fconfigure $opts(-channel) -translation binary
00162     }
00163 
00164     if {$opts(-channel) == {}} {
00165 
00166         if {[llength $args] != 1} {
00167             return -code error "wrong # args: should be\
00168                 cksum ?-format string?\
00169                 -channel chan | -filename file | string"
00170         }
00171         set tok [CksumInit]
00172         CksumUpdate $tok [lindex $args 0]
00173         set r [CksumFinal $tok]
00174     
00175     } else {
00176 
00177         set tok [CksumInit]
00178         while {![eof $opts(-channel)]} {
00179             CksumUpdate $tok [read $opts(-channel) $opts(-chunksize)]
00180         }
00181         set r [CksumFinal $tok]
00182 
00183         if {$opts(-filename) != {}} {
00184             close $opts(-channel)
00185         }
00186     }
00187 
00188     return [format $opts(-format) $r]
00189 }
00190 
00191 /*  -------------------------------------------------------------------------*/
00192 
00193 package provide cksum $::crc::cksum_version
00194 
00195 /*  -------------------------------------------------------------------------*/
00196 /*  Local variables:*/
00197 /*    mode: tcl*/
00198 /*    indent-tabs-mode: nil*/
00199 /*  End:*/
00200 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1