Created
December 5, 2021 09:02
-
-
Save IltaySaeedi/65469879115561aa98674f73f677874b to your computer and use it in GitHub Desktop.
computes CRC32B of list of bytes using Table lookUp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// A four-byte CRC (Cyclic Redundancy Code) | |
/// calculated on the preceding bytes in the chunk, | |
/// including the chunk type field and chunk data fields, | |
/// but not including the length field. | |
/// | |
/// The CRC can be used to check for corruption of the data. | |
/// The CRC is always present, even for chunks containing no data. | |
/// </summary> | |
module CRC32B = | |
// Compute CRC of a byte | |
let private crcOfByte dataByte = | |
let polyCRC32B = 0XEDB88320u | |
let mutable crc = uint dataByte | |
for bit = 0 to 7 do | |
if crc &&& 1u <> 0u then crc <- polyCRC32B ^^^ (crc >>> 1) else crc <- (crc >>> 1) | |
crc | |
// Make the table for a fast CRC. | |
let private makeCrcTable () = | |
let crcTable = | |
System.Collections.Generic.SortedDictionary<byte, uint>() | |
for n in 0uy .. 255uy do | |
let crcByte = crcOfByte n | |
crcTable.Add(n, crcByte) | |
crcTable | |
/// <summary> | |
/// computes CRC32B of list of bytes using Table lookUp | |
/// | |
/// In PNG, the 32-bit CRC is initialized to all 1's, | |
/// and then the data from each byte is processed from | |
/// the least significant bit (1) to the most significant bit (128). | |
/// | |
/// After all the data bytes are processed, | |
/// the CRC is inverted (its ones complement is taken). | |
/// This value is transmitted (stored in the datastream) MSB first. | |
/// | |
/// https://www.w3.org/TR/PNG/#D-CRCAppendix | |
/// </summary> | |
/// <returns>CRC of list of bytes</returns> | |
let compute = | |
// Table of CRCs of all 8-bit messages. | |
let lookUp = makeCrcTable () | |
let rec findCRC crc dataBytes = | |
match dataBytes with | |
| [] -> ~~~crc | |
| dataByte :: tail -> | |
let input = 0XFFuy &&& (byte crc ^^^ dataByte) | |
let lookedUpCRC = lookUp[input] ^^^ (crc >>> 8) | |
findCRC lookedUpCRC tail | |
// Initializing crc with 1s in all bits | |
findCRC 0XFFFFFFFFu |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment