UNPKG

multiformats

Version:

Interface for multihash, multicodec, multibase and CID

79 lines (67 loc) 2.37 kB
import { coerce, equals as equalBytes, toArrayBufferBackedArray } from '../bytes.ts' import * as varint from '../varint.ts' import type { MultihashDigest } from './interface.ts' /** * Creates a multihash digest. */ export function create <Code extends number> (code: Code, digest: Uint8Array): Digest<Code, number> { const size = digest.byteLength const sizeOffset = varint.encodingLength(code) const digestOffset = sizeOffset + varint.encodingLength(size) const bytes = new Uint8Array(digestOffset + size) varint.encodeTo(code, bytes, 0) varint.encodeTo(size, bytes, sizeOffset) bytes.set(digest, digestOffset) return new Digest(code, size, digest, bytes) } /** * Turns bytes representation of multihash digest into an instance. */ export function decode (multihash: Uint8Array): MultihashDigest { const bytes = coerce(multihash) const [code, sizeOffset] = varint.decode(bytes) const [size, digestOffset] = varint.decode(bytes.subarray(sizeOffset)) const digest = bytes.subarray(sizeOffset + digestOffset) if (digest.byteLength !== size) { throw new Error('Incorrect length') } return new Digest(code, size, digest, bytes) } export function equals (a: MultihashDigest, b: unknown): b is MultihashDigest { if (a === b) { return true } else { const data = b as { code?: unknown, size?: unknown, bytes?: unknown } return ( a.code === data.code && a.size === data.size && data.bytes instanceof Uint8Array && equalBytes(a.bytes, data.bytes) ) } } /** * Represents a multihash digest which carries information about the * hashing algorithm and an actual hash digest. */ export class Digest<Code extends number, Size extends number> implements MultihashDigest { readonly code: Code readonly size: Size readonly digest: Uint8Array<ArrayBuffer> readonly bytes: Uint8Array<ArrayBuffer> /** * Creates a multihash digest. */ constructor (code: Code, size: Size, digest: Uint8Array, bytes: Uint8Array) { this.code = code this.size = size this.digest = toArrayBufferBackedArray(digest) this.bytes = toArrayBufferBackedArray(bytes) } } /** * Used to check that the passed multihash has the passed code */ export function hasCode <T extends number> (digest: MultihashDigest, code: T): digest is MultihashDigest<T> { return digest.code === code }