Livt packages
Livt.Utils
Version 1.1.1
Reusable Livt utility components, including configurable CRC helpers and CRC32.
Published files (8)
tests/hashing/Crc32Test.lvt
namespace Livt.Utils.Tests.Hashing
using Livt.Utils.Hashing
/**
* Tests for Crc32 (IEEE 802.3 / zlib, reflected polynomial 0xEDB88320).
*/
@Test
component Crc32Test
{
// Shared fixture instances, signals, and observation state.
crc: Crc32
/**
* Initialises the component under test.
*/
new()
{
crc = new Crc32()
}
/**
* CRC32("") = 0x00000000
* Reset followed by ProcessFinalBlock(zeros, 0).
*/
@Test
fn TestEmptyInput()
{
crc.Reset()
var blk: byte[16] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk, 0)
assert crc.GetByte(0) == 0x00
assert crc.GetByte(1) == 0x00
assert crc.GetByte(2) == 0x00
assert crc.GetByte(3) == 0x00
}
/**
* CRC32("123456789") = 0xCBF43926
* Standard ISO 3309 / ITU-T V.42 check value.
* Little-endian bytes: 0x26, 0x39, 0xF4, 0xCB
*/
@Test
fn TestKnownVector()
{
crc.Reset()
// "123456789" = 0x31..0x39, zero-padded to 16 bytes
var blk: byte[16] = [
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk, 9)
var result: byte[4] = crc.GetCrc()
assert result[0] == 0x26
assert result[1] == 0x39
assert result[2] == 0xF4
assert result[3] == 0xCB
}
/**
* CRC32("123456789012345678") = 0xB78D9278
* First 16 bytes via ProcessBlock, last 2 via ProcessFinalBlock.
* Little-endian bytes: 0x78, 0x92, 0x8D, 0xB7
*/
@Test
fn TestMultiBlock()
{
crc.Reset()
// "1234567890123456" (16 bytes)
var blk1: byte[16] = [
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36]
crc.ProcessBlock(blk1)
// "78" (2 bytes), zero-padded to 16
var blk2: byte[16] = [
0x37, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk2, 2)
assert crc.GetByte(0) == 0x78
assert crc.GetByte(1) == 0x92
assert crc.GetByte(2) == 0x8D
assert crc.GetByte(3) == 0xB7
}
/**
* Computing the same input twice with Reset between must give the same
* result, confirming that Reset fully restores the initial state.
*/
@Test
fn TestReset()
{
// First computation
crc.Reset()
var blk: byte[16] = [
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk, 9)
var r0: byte = crc.GetByte(0)
var r1: byte = crc.GetByte(1)
var r2: byte = crc.GetByte(2)
var r3: byte = crc.GetByte(3)
// Second computation — must produce identical result
crc.Reset()
var blk2: byte[16] = [
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38,
0x39, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk2, 9)
assert crc.GetByte(0) == r0
assert crc.GetByte(1) == r1
assert crc.GetByte(2) == r2
assert crc.GetByte(3) == r3
}
/**
* CRC32(0x00) = 0xD202EF8D
* Boundary: single zero byte — exercises table entry at index 0xFF.
* Little-endian bytes: 0x8D, 0xEF, 0x02, 0xD2
*/
@Test
fn TestSingleByteZero()
{
crc.Reset()
var blk: byte[16] = [
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk, 1)
assert crc.GetByte(0) == 0x8D
assert crc.GetByte(1) == 0xEF
assert crc.GetByte(2) == 0x02
assert crc.GetByte(3) == 0xD2
}
/**
* CRC32(0xFF) = 0xFF000000
* Boundary: single 0xFF byte — exercises table entry at index 0x00.
* Little-endian bytes: 0x00, 0x00, 0x00, 0xFF
*/
@Test
fn TestSingleByteFF()
{
crc.Reset()
var blk: byte[16] = [
0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk, 1)
assert crc.GetByte(0) == 0x00
assert crc.GetByte(1) == 0x00
assert crc.GetByte(2) == 0x00
assert crc.GetByte(3) == 0xFF
}
/**
* CRC32("The quick brown fox jumps over the lazy dog") = 0x414FA339
* 43-byte input split across two ProcessBlock calls and one ProcessFinalBlock.
* Little-endian bytes: 0x39, 0xA3, 0x4F, 0x41
*/
@Test
fn TestQuickBrownFox()
{
crc.Reset()
// "The quick brown " (bytes 0-15)
var blk1: byte[16] = [
0x54, 0x68, 0x65, 0x20, 0x71, 0x75, 0x69, 0x63,
0x6B, 0x20, 0x62, 0x72, 0x6F, 0x77, 0x6E, 0x20]
crc.ProcessBlock(blk1)
// "fox jumps over t" (bytes 16-31)
var blk2: byte[16] = [
0x66, 0x6F, 0x78, 0x20, 0x6A, 0x75, 0x6D, 0x70,
0x73, 0x20, 0x6F, 0x76, 0x65, 0x72, 0x20, 0x74]
crc.ProcessBlock(blk2)
// "he lazy dog" (bytes 32-42, len=11), zero-padded to 16
var blk3: byte[16] = [
0x68, 0x65, 0x20, 0x6C, 0x61, 0x7A, 0x79, 0x20,
0x64, 0x6F, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00]
crc.ProcessFinalBlock(blk3, 11)
assert crc.GetByte(0) == 0x39
assert crc.GetByte(1) == 0xA3
assert crc.GetByte(2) == 0x4F
assert crc.GetByte(3) == 0x41
}
}