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

CRC calculation

311 views
Skip to first unread message

Swifty

unread,
Mar 27, 2012, 2:37:32 AM3/27/12
to
Before I re-invent the wheel, does anyone have the REXX code to
calculate the CRC code for a given file?

I'll probably be using Open Object Rexx on the target system, so if
there's a built-in class/function then that would be perfectly
acceptable!

--
Steve Swift
http://www.swiftys.org.uk/swifty.html
http://www.ringers.org.uk

Sahananda

unread,
Mar 27, 2012, 12:36:22 PM3/27/12
to
Googling for it came up with
http://dennisbareis.com/rexxsrc.htm
where Dennis has a crc32 calculation

hth Jon

Swifty

unread,
Mar 28, 2012, 4:51:05 PM3/28/12
to
On Tue, 27 Mar 2012 09:36:22 -0700 (PDT), Sahananda
<saha...@gmail.com> wrote:

>Googling for it came up with
>http://dennisbareis.com/rexxsrc.htm
>where Dennis has a crc32 calculation

You're obviously a better Googler than I am. I'm better when the "Go"
is missing.

Thank you!

Gerard_Schildberger

unread,
Mar 28, 2012, 9:51:28 PM3/28/12
to
Here is my version of a CRC-32 program that can be used for a file's
contents:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%
/*REXX program to compute the CRC-32 (Cylic Redundancy Check, 32
bit) */
/*checksum for a file's content [as described in ISO 3309, ITU-T V.
42].*/

parse arg iFID _ . /*iFID = input file to be
read. */
if iFid=='' then call err 'no input fileID specified.'
if _\==''|arg()>1 then call err 'illegal input file specification:'
arg(1)
crc= /*start with a CRC clean
slate.*/
do j=1 while lines(iFID)\==0
crc=CRC_32(linein(iFID),crc) /*pass 1 line at a time to
CRC_32*/
end

if j==1 then call err "file doesn't exist:" iFID

crc=bitxor(crc,'ffFFffFF'x) /*final convolution for
checksum.*/
say 'iFID=' iFID
say 'crc =' c2x(crc)
exit

err: say; say; say '***error!***'; say; say arg(1); say; say; exit 13

/*─────────────────────────────────────CRC_32
subroutine────────────────*/
CRC_32: procedure expose !.; parse arg !,$ /*arg2 is for multi-
invokes.*/
call CRC_32. /*define 8-bit index table
once. */
$=bitxor(word($ '0000000'x,1),'ffFFffFF'x) /*use user's CRC or
default.*/

do k=1 for length(!) /*start crunching the input
data.*/
?=bitxor(right($,1),substr(!,k,1)); $=bitxor('0'x||left($,
3),!.?)
end

return $ /*return with da money to
invoker*/

/*─────────────────────────────────────CRC_32.
subroutine───────────────*/
CRC_32.: if symbol('!.0')=='VAR' then return /*déjà
vu? */
_=
'77073096ee0e612c990951ba076dc419706af48fe963a5359e6495a30edb883279dcb8a4e0d5e91e97d2d98809b64c2b7eb17cbde7b82d07'
_=_||'90bf1d911db710646ab020f2f3b9714884be41de1adad47d6ddde4ebf4d4b55183d385c7136c9856646ba8c0fd62f97a8a65c9ec14015c4f'
_=_||'63066cd9fa0f3d638d080df53b6e20c84c69105ed56041e4a26771723c03e4d14b04d447d20d85fda50ab56b35b5a8fa42b2986cdbbbc9d6'
_=_||'acbcf94032d86ce345df5c75dcd60dcfabd13d5926d930ac51de003ac8d75180bfd0611621b4f4b556b3c423cfba9599b8bda50f2802b89e'
_=_||'5f058808c60cd9b2b10be9242f6f7c8758684c11c1611dabb6662d3d76dc419001db710698d220bcefd5102a71b1858906b6b51f9fbfe4a5'
_=_||'e8b8d4337807c9a20f00f9349609a88ee10e98187f6a0dbb086d3d2d91646c97e6635c016b6b51f41c6c6162856530d8f262004e6c0695ed'
_=_||'1b01a57b8208f4c1f50fc45765b0d9c612b7e9508bbeb8eafcb9887c62dd1ddf15da2d498cd37cf3fbd44c654db261583ab551cea3bc0074'
_=_||'d4bb30e24adfa5413dd895d7a4d1c46dd3d6f4fb4369e96a346ed9fcad678846da60b8d044042d7333031de5aa0a4c5fdd0d7cc95005713c'
_=_||'270241aabe0b1010c90c20865768b525206f85b3b966d409ce61e49f5edef90e29d9c998b0d09822c7d7a8b459b33d172eb40d81b7bd5c3b'
_=_||'c0ba6cadedb883209abfb3b603b6e20c74b1d29aead547399dd277af04db261573dc1683e3630b1294643b840d6d6a3e7a6a5aa8e40ecf0b'
_=_||'9309ff9d0a00ae277d079eb1f00f93448708a3d21e01f2686906c2fef762575d806567cb196c36716e6b06e7fed41b7689d32be010da7a5a'
_=_||'67dd4accf9b9df6f8ebeeff917b7be4360b08ed5d6d6a3e8a1d1937e38d8c2c44fdff252d1bb67f1a6bc57673fb506dd48b2364bd80d2bda'
_=_||'af0a1b4c36034af641047a60df60efc3a867df55316e8eef4669be79cb61b38cbc66831a256fd2a05268e236cc0c7795bb0b4703220216b9'
_=_||'5505262fc5ba3bbeb2bd0b282bb45a925cb36a04c2d7ffa7b5d0cf312cd99e8b5bdeae1d9b64c2b0ec63f226756aa39c026d930a9c0906a9'
_=_||'eb0e363f720767850500571395bf4a82e2b87a147bb12bae0cb61b3892d28e9be5d5be0d7cdcefb70bdbdf2186d3d2d4f1d4e24268ddb3f8'
_=_||'1fda836e81be16cdf6b9265b6fb077e118b7477788085ae6ff0f6a7066063bca11010b5c8f659efff862ae69616bffd3166ccf45a00ae278'
_=_||'d70dd2ee4e0483543903b3c2a7672661d06016f74969474d3e6e77dbaed16a4ad9d65adc40df0b6637d83bf0a9bcae53debb9ec547b2cf7f'
_=_||'30b5ffe9bdbdf21ccabac28a53b3933024b4a3a6bad03605cdd7069354de572923d967bfb3667a2ec4614ab85d681b022a6f2b94b40bbe37'
_=_||'c30c8ea15a05df1b2d02ef8d'
_=right(_,2**11,0) /*right justify the hex
field. */

do j=0 to 255 /*build internal (8-bit
indexed).*/
z=d2c(j); !.z=x2c(substr(_,1+j*8,8))
end

return /*done with table (& never
again)*/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%

___________________________________ Gerard Schildberger

Gerard_Schildberger

unread,
Mar 29, 2012, 1:27:39 PM3/29/12
to
On Mar 28, 8:51 pm, Gerard_Schildberger <gerar...@rrt.net> wrote:

> if _\==''|arg()>1 then call err 'illegal input file specification:'
> arg(1)

... should be one line


>       ?=bitxor(right($,1),substr(!,k,1));  $=bitxor('0'x||left($,
> 3),!.?)

... should be one line.


> _=
> '77073096ee0e612c990951ba076dc419706af48fe963a5359e6495a30edb883279dcb8a4e0­d5e91e97d2d98809b64c2b7eb17cbde7b82d07'

... should be one line.



(sigh) Brain-dead parser. You'd think that it could handle 74 bytes
of input without splitting.
_____________________________________________ Gerard Schildberger

hakan.he...@gmail.com

unread,
Mar 30, 2012, 12:32:39 PM3/30/12
to
After changing your codes variable names to something, meaningfull and to avoid illegal character($! etc) errors when executing your code in my locale ( well I don't understand the meaning of using variable names that are "special" characters instead of a meningful name, which will render the code more readable). I run OOrexx 4.1. Well when comparing the result CRC created by your snippet with 7-zip generated CRC, your programs CRC result differ from 7-zip produced CRC.

Gerard_Schildberger

unread,
Mar 30, 2012, 4:24:40 PM3/30/12
to
> After changing your codes variable names to something, meaningfull and to avoid illegal character($! etc)  errors when executing your code in my locale ( well I don't understand the meaning of using variable names that are "special" characters instead of a meningful name, which will render the code more readable). I run OOrexx 4.1. Well when comparing the result CRC created by your snippet with 7-zip generated CRC, your programs CRC result  differ from 7-zip produced CRC.- Hide quoted text -
>
> - Show quoted text -

It would help if you would show the 7-zip produced CRC. I'm assuming
it is CRC-32.
Perhaps it's in decimal?

Try replacing the 2nd SAY instruction with:

say 'hex crc-32 =' c2x(crc) left('',20) 'decimal crc-32 =' c2d(crc)

_________________________________________________ Gerard Schildberger

Gerard_Schildberger

unread,
Mar 30, 2012, 8:00:16 PM3/30/12
to
On Mar 30, 3:24 pm, Gerard_Schildberger <gerar...@rrt.net> wrote:

I rewrote the REXX program (classic REXX) to build the 8-bit internal
table instead of dragging around all those literal constants.

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%
/*REXX program to compute the CRC-32 (Cylic Redundancy Check, 32
bit) */
/*checksum for a file's content [as described in ISO 3309, ITU-T V.
42].*/

parse arg iFID _ . /*iFID = input file to be
read. */
if iFid=='' then call err 'no input fileID specified.'
if _\==''|arg()>1 then call err 'illegal input file specification:'
arg(1)
crc='' /*start with a CRC clean
slate.*/
do j=1 while lines(iFID)\==0
crc=CRC_32(linein(iFID),crc) /*pass 1 line at a time to
CRC_32*/
end

if j==1 then call err "file doesn't exist:" iFID
crc=bitxor(crc,'ffFFffFF'x) /*final convolution for
checksum.*/
say 'iFID=' iFID
say 'hex crc-32 =' c2x(crc) left('',20) 'decimal crc-32 =' c2d(crc)
exit

err: say; say; say '***error!***'; say; say arg(1); say; say; exit 13

/*─────────────────────────────────────CRC_32
subroutine────────────────*/
CRC_32: procedure expose !.; parse arg !,$ /*arg2 is for multi-
invokes.*/
call CRC_32. /*define 8-bit index table
once. */
$=bitxor(word($ '0000000'x,1),'ffFFffFF'x) /*use user's CRC or
default.*/
do k=1 for length(!) /*start crunching the input
data.*/
?=bitxor(right($,1),substr(!,k,1))
$=bitxor('0'x||left($,3),!.?)
end
return $ /*return with da money to
invoker*/

/*─────────────────────────────────────CRC_32.
subroutine───────────────*/
CRC_32.: if symbol('!.0')=='VAR' then return /*déjà
vu? */
do i=0 to 255; z=d2c(i) /*build the 8-bit indexed
table. */
r=right(z,4,'0'x) /*insure the R is 32
bits. */
do j=0 for 8 /*handle each bit of rightmost
8.*/
rb=x2b(c2x(r)) /*convert char ──> hex ──>
binary*/
_=right(rb,1) /*remember right-most bit for
IF.*/
r=x2c(b2x(0||left(rb,31))) /*shift it right (unsigned) 1
bit*/
if _\==0 then r=bitxor(r,'edb88320'x) /*bit XOR grunt-
work.*/
end
!.z=r
end
return /*done with table (& never
again)*/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%

_______________________________________________ Gerard Schildberger

hakan.he...@gmail.com

unread,
Mar 31, 2012, 7:48:13 AM3/31/12
to
I think the difference, in the calculation of CRC in your code vs 7-zip, is that you read a line at a time and 7-zip (and/or others) read a character a time and that includes CR LF etc., which is not part of the read line when calculation take place in your code. That will give different results.
Using this testfile(6 lines, last line is only '0D0A'x) and some changes to your code will show this.
123456789
123456789
1

2

And adding '0D0A'x to each line passed to CRC32 proc
!= !||'0D0A'x
and remove $=bitxor(word($ '0000000'x,1),'ffFFffFF'x) /*use user's CRC or default.*/

And also init var crc to 'ffffffff'x in the beginning.
will give CRC 7F1FABFC the same as 7-zip gives

Gerard_Schildberger

unread,
Mar 31, 2012, 11:42:36 AM3/31/12
to
> will give CRC 7F1FABFC the same as 7-zip gives- Hide quoted text -
>
> - Show quoted text -

I'll change the code to include line break characters. Also,
the CRC var IS set to 'ffFFffFF'x initially.
______________________________ Gerard Schildberger

Gerard_Schildberger

unread,
Mar 31, 2012, 4:10:42 PM3/31/12
to
Here is the latest version of a CRC-32 checksum for a file (and I
must say that the limiting of line widths to 68 really restricts
the use of wider comments):


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/* REXX program to compute the CRC-32 (Cylic Redundancy Check, */
/* 32 bit) checksum for a file's content */
/* [as described in ISO 3309, ITU-T V.42]. */

/* Some of the REXX code to handle the issuance of REXX program */
/* errors (syntax, novalue) has been elided; namely, the */
/* name and path of the REXX program, better formatted error */
/* messages, and the use of red color for error messages. */

SIGNAL on novalue /*let's handle NOVALUE error msgs*/
SIGNAL on syntax /*let's handle SYNTAX error msgs*/
call time 'R' /*reset the REXX wall clock timer*/
parse arg f _ . /*F = input file to be read. */
if f=='' then call err 'no input fileID specified.'
if _\==''|arg()>1 then call err 'illegal input fileID:' arg(1)
say
say 'input fileID being used: ' f
say
txt=''

do j=0 while lines(f)\==0 /*J count's file's chars + EOL's.*/
txt=txt||charin(f,,100000) /*read 100k chunks of data, which*/
end /*includes all End-Of-Line chars.*/

/*now, J = the file's total size.*/
if j==0 then call err "file doesn't exist or is empty.",'fileID:' f
say 'calling crc_32 with' length(txt) "bytes of data",
'(which include End-Of-Line chars).'

crc=CRC_32(txt) /*get the CRC-32 for the file. */

say
_=" hex CRC-32 =" c2x(crc) left('',9) "decimal CRC-32 =" c2d(crc)' '
say centre(_,max(79,linesize()),'-') /*highlight the CRC-32 msg. */
say
say 'Processing time used was' format(time('E'),,2) "seconds."
say
exit

/*───────────────────────────────error handling subroutines───────*/
err: say; say; say center(' error! ',max(40,linesize()%2),"*"); say
do j=1 for arg(); say arg(j); say; end; say; exit 13

novalue: syntax: call err 'REXX program' condition('C') "error",,
condition('D'),'REXX source statement (line' sigl"):",,
sourceline(sigl)

/*───────────────────────────────CRC_32 subroutine────────────────*/
CRC_32: procedure expose !. /*!.=internal 8-bit index table. */
parse arg data,key /*arg2 is for multi-invokes only.*/
call CRC_32. /*define 8-bit index table once. */
key=bitxor(word(key '0000000'x,1),'ffFFffFF'x) /*get CRC|default.*/

do while data\=='' /*keep trunkin' 'til no more data*/
parse var data chunk +2000 data /*break data into chucks.*/

do k=1 for length(chunk) /*start crunching the input data.*/
?=bitxor(right(key,1),substr(chunk,k,1)) /*get 8bit tab idx*/
key=bitxor('0'x||left(key,3),!.?) /* and get new key*/
end /*k*/

end /*while data\=='' */

return bitxor(key,'ffFFffFF'x) /*final convolution for checksum.*/

/*───────────────────────────────CRC_32. subroutine───────────────*/
CRC_32.: if symbol('!.0')=='VAR' then return /*déjà vu? */

do i=0 to 255; z=d2c(i) /*build the 8-bit indexed table. */
r=right(z,4,'0'x) /*insure the R is 32 bits. */

do j=0 for 8 /*handle each bit of rightmost 8.*/
rb=x2b(c2x(r)) /*convert char ──> hex ──> binary*/
_=right(rb,1) /*remember right-most bit for IF.*/
r=x2c(b2x(0||left(rb,31))) /*shift right (unsigned) 1 bit*/
if _\==0 then r=bitxor(r,'edb88320'x) /*bit grunt-work.*/
end /*j*/

!.z=r
end /*i*/

return /*done with table (& never again)*/
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


This version supports reading of the End-Of-Line characters (which are
treated like data), better error diagnostics/messages, and also is
quite a bit faster for bigger files. ___________ Gerard Schildberger

Swifty

unread,
Apr 3, 2012, 2:51:05 AM4/3/12
to
On Sat, 31 Mar 2012 13:10:42 -0700 (PDT), Gerard_Schildberger
<gera...@rrt.net> wrote:

>do j=0 while lines(f)\==0 /*J count's file's chars + EOL's.*/
> txt=txt||charin(f,,100000) /*read 100k chunks of data, which*/
> end

Since you're going to end up with the entire file in the string "txt",
this will often be faster (sometimes stunningly so):

txt = charin(f,,stream(f,'c','query size')

The performance gains are twofold:

1. Appending chunks to an existing variable is inefficient, as every
append (usually) requires a call to free storage management to get the
larger space required.

2. If you can perform your I/O in a single call, you eliminate much of
the I/O overhead.

I would urge people to benchmark this in the environment where they
plan to use it. You may get a very pleasant surprise, especially on
large files.

Oh, by the way - thanks for the sample code! :-)

Swifty

unread,
Apr 3, 2012, 4:32:22 AM4/3/12
to
On Sat, 31 Mar 2012 13:10:42 -0700 (PDT), Gerard_Schildberger
<gera...@rrt.net> wrote:

>Here is the latest version of a CRC-32 checksum for a file

Some other observations (I'm curious)

1. My oorexx 4.1.1 has no linesize() function.
Under Windows, Linesize: Return word(SysTextScreenSize(),2)
... gets the job done

2. I had to add "Numeric digits xx" (I chose 20) to get c2d(crc) to
work when crc is 4 characters (10 would have been sufficient digits

What made it work for you?

Incidentally, how do I get the "real" CRC32 for a file under XP (apart
from your program, of course!)

danfan46

unread,
Apr 3, 2012, 4:45:25 AM4/3/12
to
On 2012-04-03 10:32, Swifty wrote:
> On Sat, 31 Mar 2012 13:10:42 -0700 (PDT), Gerard_Schildberger
> <gera...@rrt.net> wrote:
>
>> Here is the latest version of a CRC-32 checksum for a file
>
> Some other observations (I'm curious)
>
> 1. My oorexx 4.1.1 has no linesize() function.
> Under Windows, Linesize: Return word(SysTextScreenSize(),2)
> ... gets the job done
>
> 2. I had to add "Numeric digits xx" (I chose 20) to get c2d(crc) to
> work when crc is 4 characters (10 would have been sufficient digits
>
> What made it work for you?
>
> Incidentally, how do I get the "real" CRC32 for a file under XP (apart
> from your program, of course!)
>

I wrote this subroutine:

-- ----------------------------------------
linesize: procedure

qnamn = rxqueue('Create')
address bash 'tput cols | rxqueue' qnamn
oldq = rxqueue('Set', qnamn)
parse pull width
rc = rxqueue('Delete',qnamn)
return width
-- ------------------------------------------
Could do with some errorhandling

/dg

hex

unread,
Apr 3, 2012, 1:47:38 PM4/3/12
to
Den tisdagen den 3:e april 2012 kl. 08:51:05 UTC+2 skrev Swifty:

> The performance gains are twofold:
>
> 1. Appending chunks to an existing variable is inefficient, as every
> append (usually) requires a call to free storage management to get the
> larger space required.
>
> 2. If you can perform your I/O in a single call, you eliminate much of
> the I/O overhead.
>
> I would urge people to benchmark this in the environment where they
> plan to use it. You may get a very pleasant surprise, especially on
> large files.
>
> Oh, by the way - thanks for the sample code! :-)
>
> --
> Steve Swift
> http://www.swiftys.org.uk/swifty.html
> http://www.ringers.org.uk
Another variant to avoid reading a whole file at time
the formatting can't be guarantied when pasting the code
/* This code is for OORexx 4.1 with OODialog 4.2 */
/* result is also copied to clipboard */
arg filename
if arg(1) = "" then do
call openfile
if result = 0 then do
say " "
say "** Filename required **"
exit
end
filename = result
end
crc = .crc32~new
/* 64 is multiple of 1024 blocks to read from file at time,
default is 32
*/
res = crc~crc(filename,64)


txt = "CRC " res "for file"
/* Copy result to clipboard */
NL = '0d'x
winClip = .WindowsClipboard~new
if winClip~initcode \= 0 then exit
winClip~copy(res)

text = "CRC32 for file" filename "is" ||NL NL "Hex " res ||NL
call infodialog(text)
exit
/***************************************************/
/* */
/***************************************************/
::Routine OpenFile
selfile = ' '
parent = ''
filemask = 'All Files (*.*)'
loadorsave = 'LOAD'
title = 'Input file'
defExtension = ''
multiSelect = '' r
sepChar = ''
filename = FileNameDialog(selfile,parent,filemask,loadorsave, ,
title,defExtension,multiSelect,sepChar)
return(FileName)

::requires "winSystm.cls"
::requires "OODIALOG.cls"


::CLASS MyRoutines PUBLIC
/* code modified from samples writtten by Dennis Bareis and others,
who I can't remember
but all credits to those
*/
::CLASS CRC32 subclass Myroutines public
::Method Init
expose CRC32table
self~initcrc32
return

/* ******************** InitCrc32() ***********************
* Must be called once at the start of your script, and
* then you can call Crc32(). */
::Method InitCrc32 private
expose CRC32Table

Crc32Table = "00000000 77073096 ee0e612c 990951ba 076dc419"x ||,
"706af48f e963a535 9e6495a3 0edb8832 79dcb8a4"x ||,
"e0d5e91e 97d2d988 09b64c2b 7eb17cbd e7b82d07"x ||,
"90bf1d91 1db71064 6ab020f2 f3b97148 84be41de"x ||,
"1adad47d 6ddde4eb f4d4b551 83d385c7 136c9856"x ||,
"646ba8c0 fd62f97a 8a65c9ec 14015c4f 63066cd9"x ||,
"fa0f3d63 8d080df5 3b6e20c8 4c69105e d56041e4"x ||,
"a2677172 3c03e4d1 4b04d447 d20d85fd a50ab56b"x ||,
"35b5a8fa 42b2986c dbbbc9d6 acbcf940 32d86ce3"x ||,
"45df5c75 dcd60dcf abd13d59 26d930ac 51de003a"x ||,
"c8d75180 bfd06116 21b4f4b5 56b3c423 cfba9599"x ||,
"b8bda50f 2802b89e 5f058808 c60cd9b2 b10be924"x ||,
"2f6f7c87 58684c11 c1611dab b6662d3d 76dc4190"x ||,
"01db7106 98d220bc efd5102a 71b18589 06b6b51f"x ||,
"9fbfe4a5 e8b8d433 7807c9a2 0f00f934 9609a88e"x ||,
"e10e9818 7f6a0dbb 086d3d2d 91646c97 e6635c01"x ||,
"6b6b51f4 1c6c6162 856530d8 f262004e 6c0695ed"x ||,
"1b01a57b 8208f4c1 f50fc457 65b0d9c6 12b7e950"x ||,
"8bbeb8ea fcb9887c 62dd1ddf 15da2d49 8cd37cf3"x ||,
"fbd44c65 4db26158 3ab551ce a3bc0074 d4bb30e2"x ||,
"4adfa541 3dd895d7 a4d1c46d d3d6f4fb 4369e96a"x ||,
"346ed9fc ad678846 da60b8d0 44042d73 33031de5"x ||,
"aa0a4c5f dd0d7cc9 5005713c 270241aa be0b1010"x ||,
"c90c2086 5768b525 206f85b3 b966d409 ce61e49f"x ||,
"5edef90e 29d9c998 b0d09822 c7d7a8b4 59b33d17"x ||,
"2eb40d81 b7bd5c3b c0ba6cad edb88320 9abfb3b6"x ||,
"03b6e20c 74b1d29a ead54739 9dd277af 04db2615"x ||,
"73dc1683 e3630b12 94643b84 0d6d6a3e 7a6a5aa8"x ||,
"e40ecf0b 9309ff9d 0a00ae27 7d079eb1 f00f9344"x ||,
"8708a3d2 1e01f268 6906c2fe f762575d 806567cb"x ||,
"196c3671 6e6b06e7 fed41b76 89d32be0 10da7a5a"x ||,
"67dd4acc f9b9df6f 8ebeeff9 17b7be43 60b08ed5"x ||,
"d6d6a3e8 a1d1937e 38d8c2c4 4fdff252 d1bb67f1"x ||,
"a6bc5767 3fb506dd 48b2364b d80d2bda af0a1b4c"x ||,
"36034af6 41047a60 df60efc3 a867df55 316e8eef"x ||,
"4669be79 cb61b38c bc66831a 256fd2a0 5268e236"x ||,
"cc0c7795 bb0b4703 220216b9 5505262f c5ba3bbe"x ||,
"b2bd0b28 2bb45a92 5cb36a04 c2d7ffa7 b5d0cf31"x ||,
"2cd99e8b 5bdeae1d 9b64c2b0 ec63f226 756aa39c"x ||,
"026d930a 9c0906a9 eb0e363f 72076785 05005713"x ||,
"95bf4a82 e2b87a14 7bb12bae 0cb61b38 92d28e9b"x ||,
"e5d5be0d 7cdcefb7 0bdbdf21 86d3d2d4 f1d4e242"x ||,
"68ddb3f8 1fda836e 81be16cd f6b9265b 6fb077e1"x ||,
"18b74777 88085ae6 ff0f6a70 66063bca 11010b5c"x ||,
"8f659eff f862ae69 616bffd3 166ccf45 a00ae278"x ||,
"d70dd2ee 4e048354 3903b3c2 a7672661 d06016f7"x ||,
"4969474d 3e6e77db aed16a4a d9d65adc 40df0b66"x ||,
"37d83bf0 a9bcae53 debb9ec5 47b2cf7f 30b5ffe9"x ||,
"bdbdf21c cabac28a 53b39330 24b4a3a6 bad03605"x ||,
"cdd70693 54de5729 23d967bf b3667a2e c4614ab8"x ||,
"5d681b02 2a6f2b94 b40bbe37 c30c8ea1 5a05df1b"x ||,
"2d02ef8d"x
RETURN

::Method crc
expose CRC32table
use strict arg filename,size=32
/* if one wants to use a lower value than default but not less 4 */
if size < 4 then
size = 4
a = self~Crc32Disk(Filename,size)
return a


/* *********************** Crc32 calc **********************/
::Method CRC32disk private
expose CRC32table
use strict arg fname,size
NUMERIC DIGITS 11
checksum = "FFFFFFFF"x
DO
/* Open the file */
signal on notready
f = .STREAM~new(fname)
f~open('Read')
filesize = f~CHARS

if filesize > 0 then
do
chunkssize = size*1024

do filesize%chunkssize
data = f~CHARIN(,chunkssize)
do i = 1 to data~length
E1 = bitxor(right(checksum,1),substr(data,i,1))
checksum = bitxor('0'x||left(checksum,3), ,
substr(crc32table,c2d(e1)*4+1,4))
end
end

theend = f~chars /* bytes left */
data = f~CHARIN(, theend)
do i = 1 to data~length
E1 = bitxor(right(checksum,1),substr(data,i,1))
checksum = ,
bitxor('0'x||left(checksum,3),substr(crc32table,c2d(e1)*4+1,4))
end
end
notready:
f~close
END
return c2x(bitxor(checksum, "FFFFFFFF"x))

Message has been deleted

Swifty

unread,
Apr 4, 2012, 1:56:24 AM4/4/12
to
On Tue, 3 Apr 2012 10:47:38 -0700 (PDT), hex
<hakan.he...@gmail.com> wrote:

>Another variant to avoid reading a whole file at time

More choices for me - thanks!

Jeremy Nicoll - news posts

unread,
Apr 10, 2012, 9:41:57 AM4/10/12
to
Swifty <steve....@gmail.com> wrote:

> Incidentally, how do I get the "real" CRC32 for a file under XP (apart
> from your program, of course!)

There's zillions of apps that do this - just google. I quite like the
HashMyFiles utility from http://www.nirsoft.net (where there are many other
useful things too), but it's a GUI tool.

Possibly you want a CLI one; googling "xp cli crc32" seems to find some
alternatives.

--
Jeremy C B Nicoll - my opinions are my own.

Email sent to my from-address will be deleted. Instead, please reply
to newsre...@wingsandbeaks.org.uk replacing "aaa" by "284".

Rugxulo

unread,
Apr 13, 2012, 7:07:00 PM4/13/12
to
Hi,

On Apr 10, 8:41 am, Jeremy Nicoll - news posts
<jn.nntp.scrap...@wingsandbeaks.org.uk> wrote:
> Swifty <steve.j.sw...@gmail.com> wrote:
> > Incidentally, how do I get the "real" CRC32 for a file under XP (apart
> > from your program, of course!)
>
> There's zillions of apps that do this - just google.  I quite like the
> HashMyFiles utility fromhttp://www.nirsoft.net(where there are many other
> useful things too), but it's a GUI tool.
>
> Possibly you want a CLI one; googling "xp cli crc32" seems to find some
> alternatives.

If your XP is 32-bit, here's a very very very tiny DOS tool (w/ .ASM
src) to do it:

http://sta.c64.org/crc32.zip

Also, I'm not on Windows now, but I'm fairly sure the built-in .ZIP
support in Explorer would show you the CRC32 for something, so you
could just quickly ZIP it up and see what it says. Kludgy but works,
and you wouldn't have to download anything extra.

A more universal tool (with various hashes support) would be this
small tool from FreeDOS, written in C (w/ srcs). It should (IIRC)
compile with OpenWatcom for any supported target:

http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/util/file/md5sum/3.0/

Apparently GNU coreutils doesn't have a CRC32 program, but it does
have md5sum and sha1sum, sha2*, etc.

http://www.gnu.org/software/coreutils/manual/html_node/Summarizing-files.html#Summarizing-files

http://gnuwin32.sourceforge.net/packages/coreutils.htm

P.S. With SSE4.2, there is a special CRC32 x86 instruction, but I'm
fairly?? certain that the polynomial isn't the same as most common
apps (e.g. ZIP), only for SCSI protocols or something obscure as such,
so it's not directly helpful here (but I figured I'd mention it
anyways).

http://en.wikipedia.org/wiki/SSE4

Swifty

unread,
Apr 14, 2012, 3:19:54 AM4/14/12
to
On Fri, 13 Apr 2012 16:07:00 -0700 (PDT), Rugxulo <rug...@gmail.com>
wrote:

>If your XP is 32-bit, here's a very very very tiny DOS tool

Thank you all for the various suggestions. At this point, I'll take
stock, and find out what the "user" wants to do. I'm bound to be able
to find a solution to fit the bill!
0 new messages