=encoding utf8
=head1 NAME
std/digest/crc32 - CRC32 digests for BinaryString values.
=head1 SYNOPSIS
from std/digest/crc32 import *;
let payload := to_binary( "hello" );
let raw := crc32(payload);
let hex := crc32_hex(payload);
let b64 := crc32_b64(payload);
=head1 IMPLEMENTATION SUPPORT
This module is supported by all implementations of ZuzuScript.
=head1 DESCRIPTION
This module provides CRC32 digest helpers implemented in pure
ZuzuScript.
=head1 EXPORTS
=head2 Functions
=over
=item * C<crc32(BinaryString value)>
Parameters: C<value> is binary input data. Returns: C<BinaryString>.
Returns the raw 4-byte CRC32 digest.
=item * C<crc32_hex(BinaryString value)>
Parameters: C<value> is binary input data. Returns: C<String>. Returns
the digest as lowercase hexadecimal text.
=item * C<crc32_b64(BinaryString value)>
Parameters: C<value> is binary input data. Returns: C<String>. Returns
the digest as Base64 text without trailing C<=> padding.
=back
=head1 COPYRIGHT AND LICENCE
B<< std/digest/crc32 >> is copyright Toby Inkster.
It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.
=cut
from std/string/base64 import encode, decode;
from std/string import substr, index;
let _HEX := "0123456789abcdef";
let _B64_ALPHABET := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
function _div_floor ( Number n, Number d ) {
return floor( n / d );
}
function _bytes_to_binary ( Array bytes ) {
let out := "";
let i := 0;
let n := bytes.length();
while ( i < n ) {
let b0 := bytes[i];
let b1 := null;
let b2 := null;
if ( i + 1 < n ) {
b1 := bytes[i + 1];
}
if ( i + 2 < n ) {
b2 := bytes[i + 2];
}
let c0 := _div_floor( b0, 4 );
let c1 := ( b0 & 3 ) * 16;
let c2 := 64;
let c3 := 64;
if ( b1 ≢ null ) {
c1 += _div_floor( b1, 16 );
c2 := ( b1 & 15 ) * 4;
if ( b2 ≢ null ) {
c2 += _div_floor( b2, 64 );
c3 := b2 & 63;
}
}
out _= substr( _B64_ALPHABET, c0, 1 );
out _= substr( _B64_ALPHABET, c1, 1 );
out _= c2 ≡ 64 ? "=": substr( _B64_ALPHABET, c2, 1 );
out _= c3 ≡ 64 ? "=": substr( _B64_ALPHABET, c3, 1 );
i += 3;
}
return decode(out);
}
function _u32_to_binary ( Number n ) {
let b0 := _div_floor( n, 16777216 ) & 255;
let b1 := _div_floor( n, 65536 ) & 255;
let b2 := _div_floor( n, 256 ) & 255;
let b3 := n & 255;
return _bytes_to_binary( [ b0, b1, b2, b3 ] );
}
function _byte_to_hex ( Number b ) {
let hi := _div_floor( b, 16 ) & 15;
let lo := b & 15;
return substr( _HEX, hi, 1 ) _ substr( _HEX, lo, 1 );
}
function _binary_to_bytes ( BinaryString raw ) {
let b64 := encode(raw);
let out := [];
let i := 0;
let n := length b64;
while ( i < n ) {
let c0 := index( _B64_ALPHABET, substr( b64, i, 1 ) );
let c1 := index( _B64_ALPHABET, substr( b64, i + 1, 1 ) );
let ch2 := substr( b64, i + 2, 1 );
let ch3 := substr( b64, i + 3, 1 );
let c2 := -1;
let c3 := -1;
if ( ch2 ≢ "=" ) {
c2 := index( _B64_ALPHABET, ch2 );
}
if ( ch3 ≢ "=" ) {
c3 := index( _B64_ALPHABET, ch3 );
}
out.push( c0 * 4 + _div_floor( c1, 16 ) );
if ( c2 >= 0 ) {
out.push( ( c1 & 15 ) * 16 + _div_floor( c2, 4 ) );
}
if ( c3 >= 0 ) {
out.push( ( c2 & 3 ) * 64 + c3 );
}
i += 4;
}
return out;
}
function crc32 ( BinaryString value ) {
let bytes := _binary_to_bytes(value);
let crc := 4294967295;
for ( let b in bytes ) {
crc := crc ^ b;
let i := 0;
while ( i < 8 ) {
if ( ( crc & 1 ) ≡ 1 ) {
crc := _div_floor( crc, 2 ) ^ 3988292384;
}
else {
crc := _div_floor( crc, 2 );
}
i++;
}
}
crc := ( ~crc ) & 4294967295;
return _u32_to_binary(crc);
}
function crc32_hex ( BinaryString value ) {
let digest := _binary_to_bytes( crc32(value) );
let out := "";
for ( let b in digest ) {
out _= _byte_to_hex(b);
}
return out;
}
function crc32_b64 ( BinaryString value ) {
let out := encode( crc32(value) );
while ( length out > 0 and substr( out, length out - 1, 1 ) ≡ "=" ) {
out := substr( out, 0, length out - 1 );
}
return out;
}
std/digest/crc32
Standard Library source code
CRC32 digests for BinaryString values.
Module
- Name
std/digest/crc32- Area
- Standard Library
- Source
modules/std/digest/crc32.zzm