Go CRC Code Example (Online Runner)

Go CRC-8/16/32/64 examples with preset variants, hex/decimal output, and file checksums matching the CRC tools.

Online calculator: use the site CRC text tool.

Calculation method

Each CRC preset defines width, polynomial, init value, xor-out, and reflect-in/out flags. The helper computes the CRC bit-by-bit to match the tool output.

Implementation notes

  • Package: no external dependencies; CRCs are implemented directly in Go.
  • Implementation: outputs uppercase hex or decimal values to match the tool formatting.
  • Notes: CRCs are not cryptographic; any byte change (including newlines) changes the result.

Text CRC example

go
package main

import (
	"fmt"
)

type CRCVariant struct {
	ID     string
	Width  int
	Poly   uint64
	Init   uint64
	XorOut uint64
	RefIn  bool
	RefOut bool
}

var crc32ISO = CRCVariant{ID: "crc32-iso-hdlc", Width: 32, Poly: 0x04C11DB7, Init: 0xFFFFFFFF, XorOut: 0xFFFFFFFF, RefIn: true, RefOut: true}

func reflectBits(value uint64, width int) uint64 {
	var out uint64
	for i := 0; i < width; i++ {
		if value&1 == 1 {
			out |= 1 << uint(width-1-i)
		}
		value >>= 1
	}
	return out
}

func crcMask(width int) uint64 {
	if width >= 64 {
		return ^uint64(0)
	}
	return (uint64(1) << uint(width)) - 1
}

func computeCRC(data []byte, preset CRCVariant) uint64 {
	width := preset.Width
	mask := crcMask(width)
	crc := preset.Init & mask
	topBit := uint64(1) << uint(width-1)

	for _, b := range data {
		cur := uint64(b)
		if preset.RefIn {
			cur = reflectBits(cur, 8)
		}
		crc ^= cur << uint(width-8)
		for i := 0; i < 8; i++ {
			if crc&topBit != 0 {
				crc = (crc << 1) ^ preset.Poly
			} else {
				crc <<= 1
			}
			crc &= mask
		}
	}

	if preset.RefOut {
		crc = reflectBits(crc, width)
	}
	crc ^= preset.XorOut
	return crc & mask
}

func main() {
	value := computeCRC([]byte("hello"), crc32ISO)
	fmt.Printf("%08X\n", value)
}

File CRC example

go
package main

import (
	"fmt"
	"os"
)

type CRCVariant struct {
	Width  int
	Poly   uint64
	Init   uint64
	XorOut uint64
	RefIn  bool
	RefOut bool
}

var crc64ECMA = CRCVariant{Width: 64, Poly: 0x42F0E1EBA9EA3693, Init: 0x0000000000000000, XorOut: 0x0000000000000000, RefIn: false, RefOut: false}

func reflectBits(value uint64, width int) uint64 {
	var out uint64
	for i := 0; i < width; i++ {
		if value&1 == 1 {
			out |= 1 << uint(width-1-i)
		}
		value >>= 1
	}
	return out
}

func crcMask(width int) uint64 {
	if width >= 64 {
		return ^uint64(0)
	}
	return (uint64(1) << uint(width)) - 1
}

func computeCRC(data []byte, preset CRCVariant) uint64 {
	width := preset.Width
	mask := crcMask(width)
	crc := preset.Init & mask
	topBit := uint64(1) << uint(width-1)

	for _, b := range data {
		cur := uint64(b)
		if preset.RefIn {
			cur = reflectBits(cur, 8)
		}
		crc ^= cur << uint(width-8)
		for i := 0; i < 8; i++ {
			if crc&topBit != 0 {
				crc = (crc << 1) ^ preset.Poly
			} else {
				crc <<= 1
			}
			crc &= mask
		}
	}

	if preset.RefOut {
		crc = reflectBits(crc, width)
	}
	crc ^= preset.XorOut
	return crc & mask
}

func main() {
	file, err := os.CreateTemp("", "crc-example-*.bin")
	if err != nil {
		panic(err)
	}
	defer os.Remove(file.Name())
	file.WriteString("hello")
	file.Close()

	data, err := os.ReadFile(file.Name())
	if err != nil {
		panic(err)
	}
	fmt.Printf("%016X\n", computeCRC(data, crc64ECMA))
}

Complete script (implementation + tests)

go
package main

import (
	"fmt"
	"os"
	"strconv"
)

type CRCVariant struct {
	ID     string
	Label  string
	Width  int
	Poly   uint64
	Init   uint64
	XorOut uint64
	RefIn  bool
	RefOut bool
}

var CRCVariants = []CRCVariant{
	{ID: "crc8-autosar", Label: "CRC-8/AUTOSAR", Width: 8, Poly: 0x2F, Init: 0xFF, XorOut: 0xFF, RefIn: false, RefOut: false},
	{ID: "crc8-bluetooth", Label: "CRC-8/BLUETOOTH", Width: 8, Poly: 0xA7, Init: 0x00, XorOut: 0x00, RefIn: true, RefOut: true},
	{ID: "crc8-cdma2000", Label: "CRC-8/CDMA2000", Width: 8, Poly: 0x9B, Init: 0xFF, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-darc", Label: "CRC-8/DARC", Width: 8, Poly: 0x39, Init: 0x00, XorOut: 0x00, RefIn: true, RefOut: true},
	{ID: "crc8-dvb-s2", Label: "CRC-8/DVB-S2", Width: 8, Poly: 0xD5, Init: 0x00, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-gsm-a", Label: "CRC-8/GSM-A", Width: 8, Poly: 0x1D, Init: 0x00, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-gsm-b", Label: "CRC-8/GSM-B", Width: 8, Poly: 0x49, Init: 0x00, XorOut: 0xFF, RefIn: false, RefOut: false},
	{ID: "crc8-hitag", Label: "CRC-8/HITAG", Width: 8, Poly: 0x1D, Init: 0xFF, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-i-432-1", Label: "CRC-8/I-432-1", Width: 8, Poly: 0x07, Init: 0x00, XorOut: 0x55, RefIn: false, RefOut: false},
	{ID: "crc8-i-code", Label: "CRC-8/I-CODE", Width: 8, Poly: 0x1D, Init: 0xFD, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-lte", Label: "CRC-8/LTE", Width: 8, Poly: 0x9B, Init: 0x00, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-maxim-dow", Label: "CRC-8/MAXIM-DOW", Width: 8, Poly: 0x31, Init: 0x00, XorOut: 0x00, RefIn: true, RefOut: true},
	{ID: "crc8-mifare-mad", Label: "CRC-8/MIFARE-MAD", Width: 8, Poly: 0x1D, Init: 0xC7, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-nrsc-5", Label: "CRC-8/NRSC-5", Width: 8, Poly: 0x31, Init: 0xFF, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-opensafety", Label: "CRC-8/OPENSAFETY", Width: 8, Poly: 0x2F, Init: 0x00, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-rohc", Label: "CRC-8/ROHC", Width: 8, Poly: 0x07, Init: 0xFF, XorOut: 0x00, RefIn: true, RefOut: true},
	{ID: "crc8-sae-j1850", Label: "CRC-8/SAE-J1850", Width: 8, Poly: 0x1D, Init: 0xFF, XorOut: 0xFF, RefIn: false, RefOut: false},
	{ID: "crc8-smbus", Label: "CRC-8/SMBUS", Width: 8, Poly: 0x07, Init: 0x00, XorOut: 0x00, RefIn: false, RefOut: false},
	{ID: "crc8-tech-3250", Label: "CRC-8/TECH-3250", Width: 8, Poly: 0x1D, Init: 0xFF, XorOut: 0x00, RefIn: true, RefOut: true},
	{ID: "crc8-wcdma", Label: "CRC-8/WCDMA", Width: 8, Poly: 0x9B, Init: 0x00, XorOut: 0x00, RefIn: true, RefOut: true},
	{ID: "crc16-arc", Label: "CRC-16/ARC", Width: 16, Poly: 0x8005, Init: 0x0000, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-cdma2000", Label: "CRC-16/CDMA2000", Width: 16, Poly: 0xC867, Init: 0xFFFF, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-cms", Label: "CRC-16/CMS", Width: 16, Poly: 0x8005, Init: 0xFFFF, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-dds-110", Label: "CRC-16/DDS-110", Width: 16, Poly: 0x8005, Init: 0x800D, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-dect-r", Label: "CRC-16/DECT-R", Width: 16, Poly: 0x0589, Init: 0x0000, XorOut: 0x0001, RefIn: false, RefOut: false},
	{ID: "crc16-dect-x", Label: "CRC-16/DECT-X", Width: 16, Poly: 0x0589, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-dnp", Label: "CRC-16/DNP", Width: 16, Poly: 0x3D65, Init: 0x0000, XorOut: 0xFFFF, RefIn: true, RefOut: true},
	{ID: "crc16-en-13757", Label: "CRC-16/EN-13757", Width: 16, Poly: 0x3D65, Init: 0x0000, XorOut: 0xFFFF, RefIn: false, RefOut: false},
	{ID: "crc16-genibus", Label: "CRC-16/GENIBUS", Width: 16, Poly: 0x1021, Init: 0xFFFF, XorOut: 0xFFFF, RefIn: false, RefOut: false},
	{ID: "crc16-gsm", Label: "CRC-16/GSM", Width: 16, Poly: 0x1021, Init: 0x0000, XorOut: 0xFFFF, RefIn: false, RefOut: false},
	{ID: "crc16-ibm-3740", Label: "CRC-16/IBM-3740", Width: 16, Poly: 0x1021, Init: 0xFFFF, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-ibm-sdlc", Label: "CRC-16/IBM-SDLC", Width: 16, Poly: 0x1021, Init: 0xFFFF, XorOut: 0xFFFF, RefIn: true, RefOut: true},
	{ID: "crc16-iso-iec-14443-3-a", Label: "CRC-16/ISO-IEC-14443-3-A", Width: 16, Poly: 0x1021, Init: 0xC6C6, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-kermit", Label: "CRC-16/KERMIT", Width: 16, Poly: 0x1021, Init: 0x0000, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-lj1200", Label: "CRC-16/LJ1200", Width: 16, Poly: 0x6F63, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-m17", Label: "CRC-16/M17", Width: 16, Poly: 0x5935, Init: 0xFFFF, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-maxim-dow", Label: "CRC-16/MAXIM-DOW", Width: 16, Poly: 0x8005, Init: 0x0000, XorOut: 0xFFFF, RefIn: true, RefOut: true},
	{ID: "crc16-mcrf4xx", Label: "CRC-16/MCRF4XX", Width: 16, Poly: 0x1021, Init: 0xFFFF, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-modbus", Label: "CRC-16/MODBUS", Width: 16, Poly: 0x8005, Init: 0xFFFF, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-nrsc-5", Label: "CRC-16/NRSC-5", Width: 16, Poly: 0x080B, Init: 0xFFFF, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-opensafety-a", Label: "CRC-16/OPENSAFETY-A", Width: 16, Poly: 0x5935, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-opensafety-b", Label: "CRC-16/OPENSAFETY-B", Width: 16, Poly: 0x755B, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-profibus", Label: "CRC-16/PROFIBUS", Width: 16, Poly: 0x1DCF, Init: 0xFFFF, XorOut: 0xFFFF, RefIn: false, RefOut: false},
	{ID: "crc16-riello", Label: "CRC-16/RIELLO", Width: 16, Poly: 0x1021, Init: 0xB2AA, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-spi-fujitsu", Label: "CRC-16/SPI-FUJITSU", Width: 16, Poly: 0x1021, Init: 0x1D0F, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-t10-dif", Label: "CRC-16/T10-DIF", Width: 16, Poly: 0x8BB7, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-teledisk", Label: "CRC-16/TELEDISK", Width: 16, Poly: 0xA097, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-tms37157", Label: "CRC-16/TMS37157", Width: 16, Poly: 0x1021, Init: 0x89EC, XorOut: 0x0000, RefIn: true, RefOut: true},
	{ID: "crc16-umts", Label: "CRC-16/UMTS", Width: 16, Poly: 0x8005, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc16-usb", Label: "CRC-16/USB", Width: 16, Poly: 0x8005, Init: 0xFFFF, XorOut: 0xFFFF, RefIn: true, RefOut: true},
	{ID: "crc16-xmodem", Label: "CRC-16/XMODEM", Width: 16, Poly: 0x1021, Init: 0x0000, XorOut: 0x0000, RefIn: false, RefOut: false},
	{ID: "crc32-aixm", Label: "CRC-32/AIXM", Width: 32, Poly: 0x814141AB, Init: 0x00000000, XorOut: 0x00000000, RefIn: false, RefOut: false},
	{ID: "crc32-autosar", Label: "CRC-32/AUTOSAR", Width: 32, Poly: 0xF4ACFB13, Init: 0xFFFFFFFF, XorOut: 0xFFFFFFFF, RefIn: true, RefOut: true},
	{ID: "crc32-base91-d", Label: "CRC-32/BASE91-D", Width: 32, Poly: 0xA833982B, Init: 0xFFFFFFFF, XorOut: 0xFFFFFFFF, RefIn: true, RefOut: true},
	{ID: "crc32-bzip2", Label: "CRC-32/BZIP2", Width: 32, Poly: 0x04C11DB7, Init: 0xFFFFFFFF, XorOut: 0xFFFFFFFF, RefIn: false, RefOut: false},
	{ID: "crc32-cd-rom-edc", Label: "CRC-32/CD-ROM-EDC", Width: 32, Poly: 0x8001801B, Init: 0x00000000, XorOut: 0x00000000, RefIn: true, RefOut: true},
	{ID: "crc32-cksum", Label: "CRC-32/CKSUM", Width: 32, Poly: 0x04C11DB7, Init: 0x00000000, XorOut: 0xFFFFFFFF, RefIn: false, RefOut: false},
	{ID: "crc32-iscsi", Label: "CRC-32/ISCSI (Castagnoli)", Width: 32, Poly: 0x1EDC6F41, Init: 0xFFFFFFFF, XorOut: 0xFFFFFFFF, RefIn: true, RefOut: true},
	{ID: "crc32-iso-hdlc", Label: "CRC-32/ISO-HDLC", Width: 32, Poly: 0x04C11DB7, Init: 0xFFFFFFFF, XorOut: 0xFFFFFFFF, RefIn: true, RefOut: true},
	{ID: "crc32-jamcrc", Label: "CRC-32/JAMCRC", Width: 32, Poly: 0x04C11DB7, Init: 0xFFFFFFFF, XorOut: 0x00000000, RefIn: true, RefOut: true},
	{ID: "crc32-mef", Label: "CRC-32/MEF", Width: 32, Poly: 0x741B8CD7, Init: 0xFFFFFFFF, XorOut: 0x00000000, RefIn: true, RefOut: true},
	{ID: "crc32-mpeg-2", Label: "CRC-32/MPEG-2", Width: 32, Poly: 0x04C11DB7, Init: 0xFFFFFFFF, XorOut: 0x00000000, RefIn: false, RefOut: false},
	{ID: "crc32-xfer", Label: "CRC-32/XFER", Width: 32, Poly: 0x000000AF, Init: 0x00000000, XorOut: 0x00000000, RefIn: false, RefOut: false},
	{ID: "crc64-ecma", Label: "CRC-64/ECMA-182", Width: 64, Poly: 0x42F0E1EBA9EA3693, Init: 0x0000000000000000, XorOut: 0x0000000000000000, RefIn: false, RefOut: false},
	{ID: "crc64-iso", Label: "CRC-64/ISO", Width: 64, Poly: 0x000000000000001B, Init: 0xFFFFFFFFFFFFFFFF, XorOut: 0xFFFFFFFFFFFFFFFF, RefIn: true, RefOut: true},
}

func reflectBits(value uint64, width int) uint64 {
	var out uint64
	for i := 0; i < width; i++ {
		if value&1 == 1 {
			out |= 1 << uint(width-1-i)
		}
		value >>= 1
	}
	return out
}

func crcMask(width int) uint64 {
	if width >= 64 {
		return ^uint64(0)
	}
	return (uint64(1) << uint(width)) - 1
}

func computeCRC(data []byte, preset CRCVariant) uint64 {
	width := preset.Width
	mask := crcMask(width)
	crc := preset.Init & mask
	topBit := uint64(1) << uint(width-1)

	for _, b := range data {
		cur := uint64(b)
		if preset.RefIn {
			cur = reflectBits(cur, 8)
		}
		crc ^= cur << uint(width-8)
		for i := 0; i < 8; i++ {
			if crc&topBit != 0 {
				crc = (crc << 1) ^ preset.Poly
			} else {
				crc <<= 1
			}
			crc &= mask
		}
	}

	if preset.RefOut {
		crc = reflectBits(crc, width)
	}
	crc ^= preset.XorOut
	crc &= mask
	return crc
}

func formatCRC(value uint64, width int, output string) string {
	if output == "decimal" {
		return strconv.FormatUint(value, 10)
	}
	digits := (width + 3) / 4
	return fmt.Sprintf("%0*X", digits, value)
}

func crcByID(data []byte, presetID string, output string) (string, error) {
	for _, preset := range CRCVariants {
		if preset.ID == presetID {
			value := computeCRC(data, preset)
			return formatCRC(value, preset.Width, output), nil
		}
	}
	return "", fmt.Errorf("unknown preset: %s", presetID)
}

func main() {
	// Example: compute CRC-32/ISO-HDLC over text
	value, err := crcByID([]byte("hello"), "crc32-iso-hdlc", "hex")
	if err != nil {
		panic(err)
	}
	fmt.Println("crc32-iso-hdlc(hello)=", value)

	// Example: compute CRC for a file
	file, err := os.CreateTemp("", "crc-example-*.bin")
	if err != nil {
		panic(err)
	}
	defer os.Remove(file.Name())
	file.WriteString("hello")
	file.Close()

	data, err := os.ReadFile(file.Name())
	if err != nil {
		panic(err)
	}
	fileCRC, err := crcByID(data, "crc64-ecma", "hex")
	if err != nil {
		panic(err)
	}
	fmt.Println("crc64-ecma(file)=", fileCRC)

}