On this page
std/hashes
Source EditThis module implements efficient computations of hash values for diverse Nim types. All the procs are based on these two building blocks:
If you want to implement hash procs for your custom types, you will end up writing the following kind of skeleton of code:
Example:
import std/hashes
type
Something = object
foo: int
bar: string
iterator items(x: Something): Hash =
yield hash(x.foo)
yield hash(x.bar)
proc hash(x: Something): Hash =
## Computes a Hash from `x`.
var h: Hash = 0
# Iterate over parts of `x`.
for xAtom in x:
# Mix the atom with the partial hash.
h = h !& xAtom
# Finish the hash.
result = !$h
If your custom types contain fields for which there already is a hash
proc, you can simply hash together the hash values of the individual fields:
Example:
import std/hashes
type
Something = object
foo: int
bar: string
proc hash(x: Something): Hash =
## Computes a Hash from `x`.
var h: Hash = 0
h = h !& hash(x.foo)
h = h !& hash(x.bar)
result = !$h
-d:nimPreviewHashRef
to enable hashing ref
s. It is expected that this behavior becomes the new default in upcoming versions.
==
operator, the following must hold: If two values compare equal, their hashes must also be equal.
See also
- md5 module for the MD5 checksum algorithm
- base64 module for a Base64 encoder and decoder
- sha1 module for the SHA-1 checksum algorithm
- tables module for hash tables
Imports
Types
Procs
-
proc hash(sBuf: string; sPos, ePos: int): Hash {....raises: [], tags: [], forbids: [].}
-
Efficient hashing of a string buffer, from starting position
sPos
to ending positionePos
(included).hash(myStr, 0, myStr.high)
is equivalent tohash(myStr)
.Example:
Source Editvar a = "abracadabra" doAssert hash(a, 0, 3) == hash(a, 7, 10)
-
proc hash(x: cstring): Hash {....raises: [], tags: [], forbids: [].}
-
Efficient hashing of null-terminated strings.
Example:
Source EditdoAssert hash(cstring"abracadabra") == hash("abracadabra") doAssert hash(cstring"AbracadabrA") == hash("AbracadabrA") doAssert hash(cstring"abracadabra") != hash(cstring"AbracadabrA")
-
proc hash(x: float): Hash {.inline, ...raises: [], tags: [], forbids: [].}
- Efficient hashing of floats. Source Edit
-
proc hash(x: pointer): Hash {.inline, ...raises: [], tags: [], forbids: [].}
-
Efficient
hash
overload. Source Edit -
proc hash(x: string): Hash {....raises: [], tags: [], forbids: [].}
-
Efficient hashing of strings.
See also:
Example:
Source EditdoAssert hash("abracadabra") != hash("AbracadabrA")
-
proc hash[A](aBuf: openArray[A]; sPos, ePos: int): Hash
-
Efficient hashing of portions of arrays and sequences, from starting position
sPos
to ending positionePos
(included). There must be ahash
proc defined for the element typeA
.hash(myBuf, 0, myBuf.high)
is equivalent tohash(myBuf)
.Example:
Source Editlet a = [1, 2, 5, 1, 2, 6] doAssert hash(a, 0, 1) == hash(a, 3, 4)
-
proc hash[T: tuple | object | proc | iterator {.closure.}](x: T): Hash
-
Efficient
hash
overload.Example:
# for `tuple|object`, `hash` must be defined for each component of `x`. type Obj = object x: int y: string type Obj2[T] = object x: int y: string assert hash(Obj(x: 520, y: "Nim")) != hash(Obj(x: 520, y: "Nim2")) # you can define custom hashes for objects (even if they're generic): proc hash(a: Obj2): Hash = hash((a.x)) assert hash(Obj2[float](x: 520, y: "Nim")) == hash(Obj2[float](x: 520, y: "Nim2"))
Example:
Source Edit# proc proc fn1() = discard const fn1b = fn1 assert hash(fn1b) == hash(fn1) # closure proc outer = var a = 0 proc fn2() = a.inc assert fn2 is "closure" let fn2b = fn2 assert hash(fn2b) == hash(fn2) assert hash(fn2) != hash(fn1) outer()
-
proc hash[T](x: ptr [T]): Hash {.inline.}
-
Efficient
hash
overload.Example:
Source Editvar a: array[10, uint8] assert a[0].addr.hash != a[1].addr.hash assert cast[pointer](a[0].addr).hash == a[0].addr.hash
-
proc hash[T](x: ref [T]): Hash {.inline.}
-
Efficient
hash
overload.Important: Use-d:nimPreviewHashRef
to enable hashingref
s. It is expected that this behavior becomes the new default in upcoming versions.Example: cmd: -d:nimPreviewHashRef
type A = ref object x: int let a = A(x: 3) let ha = a.hash assert ha != A(x: 3).hash # A(x: 3) is a different ref object from `a`. a.x = 4 assert ha == a.hash # the hash only depends on the address
Example: cmd: -d:nimPreviewHashRef
Source Edit# you can overload `hash` if you want to customize semantics type A[T] = ref object x, y: T proc hash(a: A): Hash = hash(a.x) assert A[int](x: 3, y: 4).hash == A[int](x: 3, y: 5).hash
-
proc hashIgnoreCase(sBuf: string; sPos, ePos: int): Hash {....raises: [], tags: [], forbids: [].}
-
Efficient hashing of a string buffer, from starting position
sPos
to ending positionePos
(included); case is ignored.Note: This uses a different hashing algorithm than
hash(string)
.hashIgnoreCase(myBuf, 0, myBuf.high)
is equivalent tohashIgnoreCase(myBuf)
.Example:
Source Editvar a = "ABracadabRA" doAssert hashIgnoreCase(a, 0, 3) == hashIgnoreCase(a, 7, 10)
-
proc hashIgnoreCase(x: string): Hash {....raises: [], tags: [], forbids: [].}
-
Efficient hashing of strings; case is ignored.
Note: This uses a different hashing algorithm than
hash(string)
.See also:
Example:
Source EditdoAssert hashIgnoreCase("ABRAcaDABRA") == hashIgnoreCase("abRACAdabra") doAssert hashIgnoreCase("abcdefghi") != hash("abcdefghi")
-
proc hashIgnoreStyle(sBuf: string; sPos, ePos: int): Hash {....raises: [], tags: [], forbids: [].}
-
Efficient hashing of a string buffer, from starting position
sPos
to ending positionePos
(included); style is ignored.Note: This uses a different hashing algorithm than
hash(string)
.hashIgnoreStyle(myBuf, 0, myBuf.high)
is equivalent tohashIgnoreStyle(myBuf)
.Example:
Source Editvar a = "ABracada_b_r_a" doAssert hashIgnoreStyle(a, 0, 3) == hashIgnoreStyle(a, 7, a.high)
-
proc hashIgnoreStyle(x: string): Hash {....raises: [], tags: [], forbids: [].}
-
Efficient hashing of strings; style is ignored.
Note: This uses a different hashing algorithm than
hash(string)
.See also:
Example:
Source EditdoAssert hashIgnoreStyle("aBr_aCa_dAB_ra") == hashIgnoreStyle("abracadabra") doAssert hashIgnoreStyle("abcdefghi") != hash("abcdefghi")
-
proc hashWangYi1(x: int64 | uint64 | Hash): Hash {.inline.}
-
Wang Yi's hash_v1 for 64-bit ints (see https://github.com/rurban/smhasher for more details). This passed all scrambling tests in Spring 2019 and is simple.
Note: It's ok to define
Source Editproc(x: int16): Hash = hashWangYi1(Hash(x))
.
© 2006–2024 Andreas Rumpf
Licensed under the MIT License.
https://nim-lang.org/docs/hashes.html