Honeycomb  0.1
Component-Model Framework
Hash.h
Go to the documentation of this file.
1 // Honeycomb, Copyright (C) 2015 NewGamePlus Inc. Distributed under the Boost Software License v1.0.
2 #pragma once
3 
4 #include "Honey/Misc/Optional.h"
5 #include "Honey/String/Bytes.h"
6 
7 namespace honey
8 {
9 
10 class String;
11 
13 namespace hash
14 {
15 
17 namespace priv { namespace murmur_constexpr
19 {
20  constexpr uint64 rotLeft(uint64 v, uint64 n) { return (v << n) | (v >> (64-n)); }
21  constexpr uint64 block(const char* data, szt i)
22  {
23  return ((uint64)data[i*8]) |
24  ((uint64)data[i*8+1]) << 8 |
25  ((uint64)data[i*8+2]) << 16 |
26  ((uint64)data[i*8+3]) << 24 |
27  ((uint64)data[i*8+4]) << 32 |
28  ((uint64)data[i*8+5]) << 40 |
29  ((uint64)data[i*8+6]) << 48 |
30  ((uint64)data[i*8+7]) << 56;
31  }
32 
33  constexpr uint64 fMix_1(uint64 k) { return k^(k >> 33); }
34  constexpr uint64 fMix_0(uint64 k) { return fMix_1((k^(k >> 33))*0xc4ceb9fe1a85ec53); }
35  constexpr uint64 fMix(uint64 k) { return fMix_0((k^(k >> 33))*0xff51afd7ed558ccd); }
36 
37  constexpr uint64 fin(uint64 h1, uint64 h2)
38  {
39  return fMix(h1+h2) + fMix(h1+h2+h2);
40  }
41 
42  constexpr uint64 c1 = 0x87c37b91114253d5;
43  constexpr uint64 c2 = 0x4cf5ad432745937f;
44 
45  constexpr uint64 tail_h1(const char* tail, szt len, uint64 h1)
46  {
47  return rotLeft((
48  ((len&15) >= 8 ? ((uint64)tail[7]) << 56 : 0) |
49  ((len&15) >= 7 ? ((uint64)tail[6]) << 48 : 0) |
50  ((len&15) >= 6 ? ((uint64)tail[5]) << 40 : 0) |
51  ((len&15) >= 5 ? ((uint64)tail[4]) << 32 : 0) |
52  ((len&15) >= 4 ? ((uint64)tail[3]) << 24 : 0) |
53  ((len&15) >= 3 ? ((uint64)tail[2]) << 16 : 0) |
54  ((len&15) >= 2 ? ((uint64)tail[1]) << 8 : 0) |
55  ((len&15) >= 1 ? ((uint64)tail[0]) : 0))
56  *c1, 31)*c2 ^ h1;
57  }
58  constexpr uint64 tail_h2(const char* tail, szt len, uint64 h2)
59  {
60  return rotLeft((
61  ((len&15) >= 15 ? ((uint64)tail[14]) << 48 : 0) |
62  ((len&15) >= 14 ? ((uint64)tail[13]) << 40 : 0) |
63  ((len&15) >= 13 ? ((uint64)tail[12]) << 32 : 0) |
64  ((len&15) >= 12 ? ((uint64)tail[11]) << 24 : 0) |
65  ((len&15) >= 11 ? ((uint64)tail[10]) << 16 : 0) |
66  ((len&15) >= 10 ? ((uint64)tail[9]) << 8 : 0) |
67  ((len&15) >= 9 ? ((uint64)tail[8]) : 0))
68  *c2, 33)*c1 ^ h2;
69  }
70 
71  constexpr uint64 loop_h1(const char* data, szt i, uint64 h1, uint64 h2)
72  {
73  return (rotLeft(rotLeft(block(data, i*2+0)*c1, 31)*c2 ^ h1, 27)+h2)*5 + 0x52dce729;
74  }
75  constexpr uint64 loop_h2(const char* data, szt i, uint64 h1, uint64 h2)
76  {
77  return (rotLeft(rotLeft(block(data, i*2+1)*c2, 33)*c1 ^ h1, 31)+loop_h1(data,i,h1,h2))*5 + 0x38495ab5;
78  }
79  constexpr uint64 loop(const char* data, szt len, szt nblocks, szt i, uint64 h1, uint64 h2)
80  {
81  return i < nblocks ? loop(data, len, nblocks, i+1, loop_h1(data,i,h1,h2), loop_h2(data,i,h1,h2)) :
82  fin(tail_h1(data+nblocks*16,len,h1) ^ (uint64)len, tail_h2(data+nblocks*16,len,h2) ^ (uint64)len);
83  }
84 } }
87 szt fast(ByteBufConst bs, szt seed = 0);
90 inline szt fast(const char* str, szt seed = 0) { return fast(ByteBufConst(reinterpret_cast<const byte*>(str), strlen(str)), seed); }
92 inline szt fast(const std::string& str, szt seed = 0) { return fast(ByteBufConst(reinterpret_cast<const byte*>(str.data()), str.length()), seed); }
94 inline szt fast(const String& str, szt seed = 0) { return fast(str.u8(), seed); }
96 inline constexpr szt fast_(const char* str, szt len, szt seed = 0) { return priv::murmur_constexpr::loop(str, len, len / 16, 0, uint64(seed), uint64(seed)); }
97 
99 struct sval : ByteArray<32>
100 {
101  typedef array<uint64,4> IntArray;
102 
103  using ByteArray::ByteArray;
104 
105  const IntArray& ints() const { return reinterpret_cast<const IntArray&>(*this); }
106  IntArray& ints() { return reinterpret_cast<IntArray&>(*this); }
107 };
108 
110 
117 inline sval secure(const char* str, optional<const sval&> key = optnull) { return secure(ByteBufConst(reinterpret_cast<const byte*>(str), strlen(str)), key); }
119 inline sval secure(const std::string& str, optional<const sval&> key = optnull) { return secure(ByteBufConst(reinterpret_cast<const byte*>(str.data()), str.length()), key); }
121 inline sval secure(const String& str, optional<const sval&> key = optnull) { return secure(str.u8(), key); }
122 
124 
130 vector<sval> secureKeys(const String& password, const Bytes& salt, int iterCount, int keyCount);
131 
132 } }
szt fast(ByteBufConst bs, szt seed)
Quickly generate a small hash value. Each seed value produces a unique hash from the same data...
Definition: Hash.cpp:99
A contiguous region of referenced (not owned by object) memory.
Definition: Buffer.h:17
vector< sval > secureKeys(const String &password, const Bytes &salt, int iterCount, int keyCount)
Generate secure keys derived from a password.
Definition: Hash.cpp:136
array< uint64, 4 > IntArray
Definition: Hash.h:101
ByteArray()=default
256-bit secure hash value
Definition: Hash.h:99
static optnull_t optnull
Null optional, use to reset an optional to an uninitialized state or test for initialization.
Definition: Optional.h:12
Buffer< const byte > ByteBufConst
Definition: Bytes.h:21
const IntArray & ints() const
Definition: Hash.h:105
constexpr szt fast_(const char *str, szt len, szt seed=0)
Compile-time version of fast() for UTF-8 strings.
Definition: Hash.h:96
unsigned long long uint64
Definition: Core.h:22
std::string u8() const
Convert to UTF-8 string.
Definition: String.h:121
Unicode UTF-16 string class, wrapper around std::u16string.
Definition: String.h:23
String of bytes.
Definition: Bytes.h:26
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
Enables any type to be optional so it can exist in an uninitialized null state.
Definition: Optional.h:52
IntArray & ints()
Definition: Hash.h:106
Fixed array of N bytes.
Definition: Bytes.h:23
sval secure(ByteBufConst bs, optional< const sval & > key)
Generate a large secure hash value.
Definition: Hash.cpp:104
Global Honeycomb namespace.