infohash

package module
v0.0.0-...-924681a Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 11, 2023 License: MIT Imports: 7 Imported by: 0

README

infohash

A hash & comparator that tells you why the hash did not match.

For example if you edit the Name field in a struct, this library will tell you that the hash did not match because the Name field was changed.

Space Complexity

Per struct, we store a "global" hash and a "local" hash for each field. The global hash is 64 bits long, and the local hashes are 32 bits long. We use hamming codes to detect which "local" hash has changed. This requires us to store log2(nr_fields+1) 32 bit parity hashes instead of nr_fields 32 bit hashes. The total space complexity is therefore:

64 + log2(nr_fields+1) * 32 bits
= 8 + log2(nr_fields+1) * 4 bytes
= 16 + log2(nr_fields+1) * 8 hex characters

As a rule of thumb, this library is only useful if you have at least +-7 fields, otherwise you can just store the hashes of each field individually.

Safety

This library will detect any changes to the struct (with collision chance of 1/2^32, accounting for birthday attack). However, accurately detecting which field changed is only possible if only one field changed. If multiple fields changed, we can only detect that at least one field changed, but not which one. This is because we use hamming codes to detect which field changed, and hamming codes can only detect single field errors.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CompareHashStruct

func CompareHashStruct(obj interface{}, existingHash []byte) error

The CompareHashStruct function compares the hash of the given struct with the given hash. The passed object must be a pointer to a struct. The struct must have a non-empty tag "infohash" on each of its fields, the tag value must be unique for each field. The tag value is used as the name of the field in the returned error in case of a mismatch.

If the hash matches, the function returns nil. If the hash does not match, the function returns a FieldChangedError. If there is only one field that has changed, the error contains the name of the field. If there are multiple fields that have changed, the error contains an empty string.

func HashStruct

func HashStruct(obj interface{}) ([]byte, error)

HashStruct returns an infohash of the given struct. The passed object must be a pointer to a struct. The struct must have a non-empty tag "infohash" on each of its fields, the tag value must be unique for each field. The tag value is used as the name of the field in the returned error in case of a mismatch.

The CompareHashStruct function can be used to compare the hash of a struct with a previously calculated hash and return an error if the struct has changed. The error contains the name of the field that has changed.

func TestStructDefinition

func TestStructDefinition(t *testing.T, obj interface{}, expectedHash []byte)

This test function must be added to the unit tests in your project. It will make sure that the defined fields of the struct are not changed, which would yield all calculated hashes invalid.

Types

type FieldChangedError

type FieldChangedError struct {
	Field string
}

func (FieldChangedError) Error

func (e FieldChangedError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL