Hashing, especially SHA256, is used a lot for generating short hashes for binary and text blobs.
use crypto::hmac;
use crypto::mac;
use crypto::sha256;
use encoding::hex;
use fmt;
use hash;
use hash::crc64;
use hash::fnv;
export fn main() void = {
// CRC64, a non-cryptographic hash, is good for sending data to
// verify checksums.
const crc64state = crc64::crc64(&crc64::iso_table);
defer hash::close(&crc64state);
// Since the state embeds hash::hash we can use those functions
// to write data to it.
const crc64sz = hash::write(&crc64state,
['h', 'a', 'r', 'e']: []u8);
fmt::printf("Wrote {} bytes to the hash\n", crc64sz)!;
fmt::println("CRC64 hash", crc64::sum64(&crc64state))!;
// FNV is another non-cryptographic hash available which is well
// suited for hashmap keys.
const fnv64state = fnv::fnv64a();
defer hash::close(&fnv64state);
const fnv64sz = hash::write(&fnv64state,
['h', 'a', 'r', 'e']: []u8);
fmt::printf("Wrote {} bytes to the hash\n", fnv64sz)!;
fmt::println("FNV64 hash", fnv::sum64(&fnv64state))!;
// FNV has functions to quicky hash strings
fmt::println(fnv::string64("hare"))!;
// Moving over to cryptographic hashes like SHA256 we can first
// create the state and perform the same hashing.
const sha256state = sha256::sha256();
defer hash::close(&sha256state);
const sha256sz = hash::write(&sha256state,
['h', 'a', 'r', 'e']: []u8);
fmt::printf("Wrote {} bytes to the hash\n", sha256sz)!;
// In order to get the results of the hash we set up an array
// with the final size of the hash.
let sha256sum: [sha256::SZ]u8 = [0...];
// We use sum to compute the result and tell it to write it to
// the array we defined above, but we need to convert it to a
// slice with the [..] notation.
hash::sum(&sha256state, sha256sum[..]);
// Finally, we can encode those bytes to a hex-encoded string
// for printing
fmt::println("SHA256 hash", hex::encodestr(sha256sum[..])!)!;
// As an added bonus here we can go even further and use the
// SHA256 hash to create HMAC signatures of data.
//
// Let's create a SHA256 HMAC state with a secret key.
const secret: []u8 = ['s', '3', 'c', 'r', '3', 't', '!'];
// Sign the SHA256 state from above with the provide secret and
// write it to the buffer we set up.
const sha256mac = hmac::sha256(secret);
defer mac::finish(&sha256mac);
const sha256macsz = mac::write(&sha256mac,
['h', 'a', 'r', 'e']: []u8);
fmt::printf("Wrote {} bytes to the mac\n", sha256macsz)!;
let sha256macsum: [sha256::SZ]u8 = [0...];
mac::sum(&sha256mac, sha256macsum);
// Use the same hex encoding from before to see the final
// signature.
fmt::println("SHA256 HMAC signature",
hex::encodestr(sha256macsum[..])!)!;
};
$ hare run hashing.ha
4/4 tasks completed (100%)
Wrote 4 bytes to the hash
CRC64 hash 3660797679748775936
Wrote 4 bytes to the hash
FNV64 hash 3331174764119615823
3331174764119615823
Wrote 4 bytes to the hash
SHA256 hash e39f1cde9e9c4fac32cdd2c6772fe79c2f9fdce918679462009de1887c5ac4d7
Wrote 4 bytes to the mac
SHA256 HMAC signature d0989ad9f3abea0dab302b563a0599e5544539afd1d0545ac9e92ddae75fc6eb
Back to table of contents