Go¶
A guide to using iscc-lib from Go. The Go package is a pure Go implementation of all ISCC algorithms
— no cgo, no shared libraries, no external files. Install via go get and call package-level
functions directly.
Installation¶
Code generation¶
All 10 Gen*V0 functions are package-level functions that return typed result structs and error.
The result struct's Iscc field contains the ISCC code string prefixed with ISCC:. Optional
parameters use nil (for pointer types) or a default value.
Meta-Code¶
Generate a Meta-Code from content metadata (title, description, structured metadata):
result, err := iscc.GenMetaCodeV0("Die Unendliche Geschichte", nil, nil, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:AAA..."
// With description
desc := "Von Michael Ende"
result, err = iscc.GenMetaCodeV0("Die Unendliche Geschichte", &desc, nil, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc)
// With structured metadata (JSON string)
meta := `{"title": "Example", "author": "Author"}`
result, err = iscc.GenMetaCodeV0("Example Title", nil, &meta, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc)
Parameters: name string, description *string, meta *string, bits uint32. Pass nil for
description or meta to omit those fields. Returns *MetaCodeResult with fields Iscc, Name,
Description, Meta, Metahash.
Text-Code¶
Generate a Text-Code from plain text content:
result, err := iscc.GenTextCodeV0("Hello World", 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:EAA..."
Returns *TextCodeResult with fields Iscc and Characters.
Image-Code¶
Generate an Image-Code from a 32x32 grayscale thumbnail (1024 bytes):
// Pre-process your image to 32x32 grayscale externally
pixels := make([]byte, 1024)
for i := range pixels {
pixels[i] = 128 // Placeholder: uniform gray
}
result, err := iscc.GenImageCodeV0(pixels, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:EEA..."
Audio-Code¶
Generate an Audio-Code from a Chromaprint fingerprint vector (signed integers):
// Obtain Chromaprint features externally
fingerprint := []int32{123456, -789012, 345678, 901234}
result, err := iscc.GenAudioCodeV0(fingerprint, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:EIA..."
Video-Code¶
Generate a Video-Code from MPEG-7 frame signature vectors:
// Each frame signature is a slice of 380 integers
frame1 := make([]int32, 380)
frame2 := make([]int32, 380)
for i := range frame2 {
frame2[i] = 1
}
frameSigs := [][]int32{frame1, frame2}
result, err := iscc.GenVideoCodeV0(frameSigs, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:EMA..."
Mixed-Code¶
Combine multiple Content-Codes of different types into a Mixed-Code:
textResult, err := iscc.GenTextCodeV0("Hello World", 64)
if err != nil {
log.Fatal(err)
}
pixels := make([]byte, 1024)
for i := range pixels {
pixels[i] = 128
}
imageResult, err := iscc.GenImageCodeV0(pixels, 64)
if err != nil {
log.Fatal(err)
}
result, err := iscc.GenMixedCodeV0([]string{textResult.Iscc, imageResult.Iscc}, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:EQA..."
Data-Code¶
Generate a Data-Code from raw bytes using content-defined chunking and MinHash:
data := bytes.Repeat([]byte("Hello World"), 1000)
result, err := iscc.GenDataCodeV0(data, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:GAA..."
Instance-Code¶
Generate an Instance-Code from raw bytes using BLAKE3 hashing:
data := []byte("Hello World")
result, err := iscc.GenInstanceCodeV0(data, 64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:IAA..."
ISCC-CODE¶
Combine individual ISCC unit codes into a composite ISCC-CODE:
data := bytes.Repeat([]byte("Hello World"), 1000)
dataResult, err := iscc.GenDataCodeV0(data, 64)
if err != nil {
log.Fatal(err)
}
instanceResult, err := iscc.GenInstanceCodeV0(data, 64)
if err != nil {
log.Fatal(err)
}
result, err := iscc.GenIsccCodeV0(
[]string{dataResult.Iscc, instanceResult.Iscc}, false,
)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:KAA..."
Sum-Code¶
Generate a composite ISCC-CODE from a file in a single pass:
os.WriteFile("example.bin", bytes.Repeat([]byte("Hello World"), 1000), 0644)
result, err := iscc.GenSumCodeV0("example.bin", 64, false, false)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // "ISCC:KAA..."
fmt.Println(result.Datahash) // Multihash of the data
fmt.Println(result.Filesize) // Size in bytes
Streaming¶
For large files, use DataHasher and InstanceHasher to process data in chunks without loading
everything into memory. Both follow the NewHasher → Push → Finalize pattern.
DataHasher¶
hasher := iscc.NewDataHasher()
f, err := os.Open("large_file.bin")
if err != nil {
log.Fatal(err)
}
defer f.Close()
buf := make([]byte, 65536)
for {
n, err := f.Read(buf)
if n > 0 {
hasher.Push(buf[:n])
}
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
}
result, err := hasher.Finalize(64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // Identical to iscc.GenDataCodeV0(entireFile, 64)
InstanceHasher¶
hasher := iscc.NewInstanceHasher()
f, err := os.Open("large_file.bin")
if err != nil {
log.Fatal(err)
}
defer f.Close()
buf := make([]byte, 65536)
for {
n, err := f.Read(buf)
if n > 0 {
hasher.Push(buf[:n])
}
if err == io.EOF {
break
}
if err != nil {
log.Fatal(err)
}
}
result, err := hasher.Finalize(64)
if err != nil {
log.Fatal(err)
}
fmt.Println(result.Iscc) // Identical to iscc.GenInstanceCodeV0(entireFile, 64)
Both hashers are single-use: after calling Finalize, do not call Push or Finalize again.
Text utilities¶
Text normalization functions used internally by the code generation pipeline are available for preprocessing your own text inputs. These are pure functions that return a value directly (no error).
// Normalize text for display (NFKC, control char removal, line ending normalization)
cleaned := iscc.TextClean(" Hello\r\n\r\n\r\nWorld ")
fmt.Println(cleaned) // "Hello\n\nWorld"
// Remove newlines and collapse whitespace to single spaces
singleLine := iscc.TextRemoveNewlines("Hello\nWorld\nFoo")
fmt.Println(singleLine) // "Hello World Foo"
// Trim text so UTF-8 byte size does not exceed a limit
trimmed := iscc.TextTrim("Hello World", 5)
fmt.Println(trimmed) // "Hello"
// Simplify text for similarity hashing (lowercase, strip whitespace/punctuation)
collapsed := iscc.TextCollapse("Hello, World!")
fmt.Println(collapsed) // "helloworld"
Algorithm primitives¶
Low-level algorithm functions are available for advanced use cases:
// Sliding window: overlapping substrings of width Unicode characters
windows, err := iscc.SlidingWindow("Hello World", 4)
if err != nil {
log.Fatal(err)
}
fmt.Println(windows) // ["Hell", "ello", "llo ", "lo W", "o Wo", " Wor", "Worl", "orld"]
Additional primitives:
AlgMinhash256(features []uint32) []byte— compute a 256-bit MinHash digest from featuresAlgCdcChunks(data []byte, utf32 bool, avgChunkSize uint32) ([][]byte, error)— split data into content-defined chunksAlgSimhash(digests [][]byte) ([]byte, error)— compute a SimHash from equal-length byte digests
Codec operations¶
Functions for encoding, decoding, and decomposing ISCC codes. These operate on the ISCC binary format defined in ISO 24138.
Encode and decode¶
Construct an ISCC unit from raw header fields and digest, then decode it back:
// Encode: maintype=0 (Meta), subtype=0, version=0, 64 bits, 8-byte digest
digest := []byte{0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}
code, err := iscc.EncodeComponent(0, 0, 0, 64, digest)
if err != nil {
log.Fatal(err)
}
fmt.Println(code) // ISCC unit string (without "ISCC:" prefix)
// Decode: parse an ISCC unit string back into its header components and digest
decoded, err := iscc.IsccDecode(code)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Maintype: %d, Subtype: %d, Version: %d, Length: %d\n",
decoded.Maintype, decoded.Subtype, decoded.Version, decoded.Length)
fmt.Printf("Digest: %x\n", decoded.Digest)
IsccDecode returns a *DecodeResult with fields Maintype, Subtype, Version, Length
(length index), and Digest (raw bytes).
Decompose¶
Split a composite ISCC-CODE into its individual unit codes:
// Generate a composite ISCC-CODE first
data := bytes.Repeat([]byte("Hello World"), 1000)
dataResult, _ := iscc.GenDataCodeV0(data, 64)
instanceResult, _ := iscc.GenInstanceCodeV0(data, 64)
isccResult, _ := iscc.GenIsccCodeV0(
[]string{dataResult.Iscc, instanceResult.Iscc}, false,
)
// Decompose into individual units
units, err := iscc.IsccDecompose(isccResult.Iscc)
if err != nil {
log.Fatal(err)
}
for _, unit := range units {
fmt.Println(unit) // Each unit code (without "ISCC:" prefix)
}
Other codec functions¶
EncodeBase64(data []byte) string— encode bytes to base64url (no padding)JsonToDataUrl(jsonStr string) (string, error)— convert a JSON string to adata:application/json;base64,...URLSoftHashVideoV0(frameSigs [][]int32, bits uint32) ([]byte, error)— compute a video similarity hash from MPEG-7 frame signatures
Constants¶
Package-level constants used by the ISCC algorithms:
import iscc "github.com/iscc/iscc-lib/packages/go"
iscc.MetaTrimName // 128 — max byte length for name normalization
iscc.MetaTrimDescription // 4096 — max byte length for description normalization
iscc.IoReadSize // 4_194_304 — default read buffer size (4 MB)
iscc.TextNgramSize // 13 — n-gram size for text similarity hashing
Conformance testing¶
Verify that the library produces correct results for all official test vectors:
ok, err := iscc.ConformanceSelftest()
if err != nil {
log.Fatal(err)
}
fmt.Println("Conformance:", ok) // true
Error handling¶
All code generation functions return error as the last return value, following idiomatic Go error
handling. Errors indicate invalid input (wrong bit count, empty data where content is required,
etc.):