needs hal/instr io/stream unit num/crc code reflect ( n -- n ) W) &) A>) @, 0 i) @, 32 i) S>) @, begin 1 i) <<, 1 A) &) &nf, ifnz, 1 i) |, then 1 i) A>) >>, 1 i) S>) -, ?brnz, exit, : crc, ( poly -- ) >r \ V1=poly PSP) ^, nip, 8 i) S>) @, [compile] begin \ counter in S A) &) !, 1 i) >>, 1 i) A>) &, ifnz, r> ( poly ) i) ^, [compile] then 1 i) S>) -, ?brnz, ; : crcrev, ( shift poly -- ) >r r! ?dup if i) <<, then \ V1=poly V2=shift PSP) ^, nip, 8 i) S>) @, [compile] begin \ counter in S A) &) !, 1 i) <<, $80 r> ( shift ) lshift i) A>) &, ifnz, r> ( poly ) i) ^, [compile] then 1 i) S>) -, ?brnz, ; code acc32 ( crc c -- crc ) $04c11db7 reflect crc, exit, code acc16 ( crc c -- crc ) 8 $1021 crcrev, $ffff i) &, exit, sysalias crcword) CRCWORD acccrc : done32 inv ; : done16 $ffff and ; variable CRCDONE CRCDONE @alias crcdone : crc32$ ( -- init ) ['] acc32 CRCWORD ! ['] done32 CRCDONE ! -1 ; : crc16$ ( -- init ) ['] acc16 CRCWORD ! ['] done16 CRCDONE ! 0 ; : acccrc[] ( crc a u -- crc ) 0 do ( crc a ) tuck c@ acccrc swap 1+ loop drop ; :~ rot> acccrc[] crcdone ; : crc32[] crc32$ ~ ; : crc16[] crc16$ ~ ; : crc ( stream init -- crc ) swap >r begin ( crc ) \ V1=file -1 V1 readbuf ?dup while ( crc a u ) acccrc[] repeat ( crc ) rdrop crcdone ; : crc16 crc16$ crc ; : crc32 crc32$ crc ; : crc<< ( init -- crc ) word openpath swap crc ; : crc32<< crc32$ crc<< ; : crc16<< crc16$ crc<< ;