------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- This file is part of 'CRC32' -- -- -- -- You do not have, nor can you ever acquire the right to use, copy or -- -- distribute this software ; Should you use this software for any purpose, -- -- or copy and distribute it to anyone or in any manner, you are breaking -- -- the laws of whatever soi-disant jurisdiction, and you promise to -- -- continue doing so for the indefinite future. In any case, please -- -- always : read and understand any software ; verify any PGP signatures -- -- that you use - for any purpose. -- -- -- -- See also http://trilema.com/2015/a-new-software-licensing-paradigm . -- ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ -- CRC32, modulo 2 based implementation -- S.MG, 2018 -- -- The CRC32 is a checksum calculated as the remainder of dividing -- the input data by the 0x04C11DB7 polynomial. Specifications: -- Name : "CRC-32" -- Width : 32 (number of bits) -- Poly : 04C11DB7 (generator polynomial) -- Init : FFFFFFFF -- RefIn : True (input is reflected) -- RefOut : True (output is reflected) -- XorOut : FFFFFFFF -- Check : CBF43926 (expected value for input "123456789") -- -- This implementation is based on the CRC32 example in: -- Ross N. Williams, A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHMS -- version 3, 1993 -- http://ross.net/crc/download/crc_v3.txt with Interfaces; use Interfaces; package CRC32 is -- local, shorthand version of Interfaces. types subtype CRC32 is Interfaces.Unsigned_32; subtype Octet is Interfaces.Unsigned_8; type Octet_Array is array( Integer range <> ) of Octet; -- interface for external callers -- calculate CRC32 for the given string function CRC( S: in String ) return CRC32; -- calculate CRC32 for the given array of octets function CRC( Data: in Octet_Array ) return CRC32; -- internal constants and helper methods private -- These functions need to be imported to get to the shift operators. -- (Specific for GNAT) function Shift_Left ( Value : CRC32; Amount : Natural ) return CRC32; function Shift_Right ( Value : CRC32; Amount : Natural ) return CRC32; function Rotate_Left ( Value : CRC32; Amount : Natural ) return CRC32; function Rotate_Right ( Value : CRC32; Amount : Natural ) return CRC32; pragma Import ( Intrinsic, Rotate_Left ); pragma Import ( Intrinsic, Rotate_Right ); pragma Import ( Intrinsic, Shift_Left ); pragma Import ( Intrinsic, Shift_Right ); -- The Shift_Left instruction does not return the bit that was shifted -- We need a mask for this last bit -- Bits are counted from right to left, starting at 0 Bit31 : constant CRC32 := 16#80_00_00_00#; procedure CRC_Step(C : in out CRC32; R : in out CRC32); pragma Inline_Always(CRC_Step); function Bits_Reverse(A : in CRC32) return CRC32; end CRC32;