14 | #include "cocoa.hpp"
15 |
16 | int main() {
17 | std::string hash = cocoa::SHA1("hello world");
18 | std::cout << hash << std::endl;
19 | assert( cocoa::SHA1("hello world") == cocoa::SHA1("hello world") );
20 | return 0;
21 | }
22 | ```
23 |
24 | ### Possible output
25 | ---------------
26 |
27 | ~/cocoa>./test
28 | 2aae6c35c94fcfb415dbe95f408b9ce91ee846ed
29 | ~/cocoa>
30 |
31 |
32 | ### C++03
33 | Check old [c++03 version here](https://github.com/r-lyeh/cocoa/tree/c70a878eae074f73ae7f5222503538c130fd6a0d)
34 |
35 | ### API
36 | For more details check the [tests.cxx](tests.cxx) file.
37 |
38 | ### Cocoa::hash() API
39 | - @todocument
40 |
41 | ### Changelog
42 | - v1.0.0 (2015/06/12)
43 | - Removed warning
44 | - v0.0.0 (2010/xx/xx)
45 | - Initial commit
46 |
47 |
--------------------------------------------------------------------------------
/cocoa.cpp:
--------------------------------------------------------------------------------
1 | #include "cocoa.hpp"
2 |
--------------------------------------------------------------------------------
/cocoa.hpp:
--------------------------------------------------------------------------------
1 | /* Cocoa, an amalgamation of hashing algorithms.
2 | * CRC32, CRC64, GCRC, RS, JS, PJW, ELF, BKDR, SBDM, DJB, DJB2, BP, FNV, FNV1a, AP, BJ1, MH2, SHA1, SFH
3 | * Copyright (c) 2010,2011,2012,2013,2014 Mario 'rlyeh' Rodriguez, zlib/libpng licensed
4 |
5 | * This source file is based on code from Arash Partow (http://www.partow.net)
6 | * plus the original and credited authors for each algorithm. Thanks everybody!
7 |
8 | * To do:
9 | * - add MD5
10 | * - add comparison operators (>,<=,>=)
11 | * - add adler32 hashing
12 | * - add perfect hashing ( ref: http://cmph.sourceforge.net/index.html || http://burtleburtle.net/bob/hash/perfect.html )
13 | * - add boost hashing: seed ^= hash_value(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2);
14 |
15 | * - rlyeh
16 | */
17 |
18 | #pragma once
19 |
20 | #include
21 |
22 | #include
23 | #include
24 | #include
25 |
26 | #include
27 | #include
28 | #include
29 | #include
30 |
31 | #define COCOA_VERSION "1.0.0" /* (2015/06/12) Removed warnings
32 | #define COCOA_VERSION "0.0.0" // (2010/xx/xx) Initial commit */
33 |
34 | namespace cocoa
35 | {
36 | typedef std::uint32_t basetype;
37 | enum { basebits = sizeof(basetype) * 8 };
38 |
39 | struct use {
40 | using hash = std::vector;
41 |
42 | enum enumeration {
43 | CRC32,CRC64,GCRC,RS,JS,PJW,ELF,BKDR,SDBM,DJB,DJB2,BP,FNV,FNV1a,AP,BJ1,MH2,SHA1,SFH
44 | };
45 |
46 | static
47 | bool is_little_endian() {
48 | const long endian = 1;
49 | return ((char*)&endian)[0] > 0;
50 | }
51 |
52 | static
53 | bool is_big_endian() {
54 | return !is_little_endian();
55 | }
56 |
57 | // CRC32
58 | static hash fCRC32( const void *pMem, size_t iLen, hash my_hash = { 0 } )
59 | {
60 | if( pMem == 0 || iLen == 0 ) return my_hash;
61 |
62 | static const basetype crcTable[16] =
63 | {
64 | 0x00000000, 0x1DB71064, 0x3B6E20C8, 0x26D930AC,
65 | 0x76DC4190, 0x6B6B51F4, 0x4DB26158, 0x5005713C,
66 | 0xEDB88320, 0xF00F9344, 0xD6D6A3E8, 0xCB61B38C,
67 | 0x9B64C2B0, 0x86D3D2D4, 0xA00AE278, 0xBDBDF21C
68 | };
69 |
70 | const unsigned char *pPtr = (const unsigned char *)pMem;
71 | basetype h = ~my_hash[0];
72 |
73 | while( iLen-- )
74 | {
75 | h ^= (*pPtr++);
76 | h = crcTable[h & 0x0f] ^ (h >> 4);
77 | h = crcTable[h & 0x0f] ^ (h >> 4);
78 | }
79 |
80 | return { ~h };
81 | }
82 |
83 | // CRC64-ECMA
84 | static hash fCRC64( const void *pMem, size_t iLen, hash my_hash = { 0, 0 } )
85 | {
86 | if( pMem == 0 || iLen == 0 ) return my_hash;
87 |
88 | static const std::uint64_t crcTable[256] =
89 | {
90 | 0x0000000000000000ULL, 0x42F0E1EBA9EA3693ULL, 0x85E1C3D753D46D26ULL, 0xC711223CFA3E5BB5ULL,
91 | 0x493366450E42ECDFULL, 0x0BC387AEA7A8DA4CULL, 0xCCD2A5925D9681F9ULL, 0x8E224479F47CB76AULL,
92 | 0x9266CC8A1C85D9BEULL, 0xD0962D61B56FEF2DULL, 0x17870F5D4F51B498ULL, 0x5577EEB6E6BB820BULL,
93 | 0xDB55AACF12C73561ULL, 0x99A54B24BB2D03F2ULL, 0x5EB4691841135847ULL, 0x1C4488F3E8F96ED4ULL,
94 | 0x663D78FF90E185EFULL, 0x24CD9914390BB37CULL, 0xE3DCBB28C335E8C9ULL, 0xA12C5AC36ADFDE5AULL,
95 | 0x2F0E1EBA9EA36930ULL, 0x6DFEFF5137495FA3ULL, 0xAAEFDD6DCD770416ULL, 0xE81F3C86649D3285ULL,
96 | 0xF45BB4758C645C51ULL, 0xB6AB559E258E6AC2ULL, 0x71BA77A2DFB03177ULL, 0x334A9649765A07E4ULL,
97 | 0xBD68D2308226B08EULL, 0xFF9833DB2BCC861DULL, 0x388911E7D1F2DDA8ULL, 0x7A79F00C7818EB3BULL,
98 | 0xCC7AF1FF21C30BDEULL, 0x8E8A101488293D4DULL, 0x499B3228721766F8ULL, 0x0B6BD3C3DBFD506BULL,
99 | 0x854997BA2F81E701ULL, 0xC7B97651866BD192ULL, 0x00A8546D7C558A27ULL, 0x4258B586D5BFBCB4ULL,
100 | 0x5E1C3D753D46D260ULL, 0x1CECDC9E94ACE4F3ULL, 0xDBFDFEA26E92BF46ULL, 0x990D1F49C77889D5ULL,
101 | 0x172F5B3033043EBFULL, 0x55DFBADB9AEE082CULL, 0x92CE98E760D05399ULL, 0xD03E790CC93A650AULL,
102 | 0xAA478900B1228E31ULL, 0xE8B768EB18C8B8A2ULL, 0x2FA64AD7E2F6E317ULL, 0x6D56AB3C4B1CD584ULL,
103 | 0xE374EF45BF6062EEULL, 0xA1840EAE168A547DULL, 0x66952C92ECB40FC8ULL, 0x2465CD79455E395BULL,
104 | 0x3821458AADA7578FULL, 0x7AD1A461044D611CULL, 0xBDC0865DFE733AA9ULL, 0xFF3067B657990C3AULL,
105 | 0x711223CFA3E5BB50ULL, 0x33E2C2240A0F8DC3ULL, 0xF4F3E018F031D676ULL, 0xB60301F359DBE0E5ULL,
106 | 0xDA050215EA6C212FULL, 0x98F5E3FE438617BCULL, 0x5FE4C1C2B9B84C09ULL, 0x1D14202910527A9AULL,
107 | 0x93366450E42ECDF0ULL, 0xD1C685BB4DC4FB63ULL, 0x16D7A787B7FAA0D6ULL, 0x5427466C1E109645ULL,
108 | 0x4863CE9FF6E9F891ULL, 0x0A932F745F03CE02ULL, 0xCD820D48A53D95B7ULL, 0x8F72ECA30CD7A324ULL,
109 | 0x0150A8DAF8AB144EULL, 0x43A04931514122DDULL, 0x84B16B0DAB7F7968ULL, 0xC6418AE602954FFBULL,
110 | 0xBC387AEA7A8DA4C0ULL, 0xFEC89B01D3679253ULL, 0x39D9B93D2959C9E6ULL, 0x7B2958D680B3FF75ULL,
111 | 0xF50B1CAF74CF481FULL, 0xB7FBFD44DD257E8CULL, 0x70EADF78271B2539ULL, 0x321A3E938EF113AAULL,
112 | 0x2E5EB66066087D7EULL, 0x6CAE578BCFE24BEDULL, 0xABBF75B735DC1058ULL, 0xE94F945C9C3626CBULL,
113 | 0x676DD025684A91A1ULL, 0x259D31CEC1A0A732ULL, 0xE28C13F23B9EFC87ULL, 0xA07CF2199274CA14ULL,
114 | 0x167FF3EACBAF2AF1ULL, 0x548F120162451C62ULL, 0x939E303D987B47D7ULL, 0xD16ED1D631917144ULL,
115 | 0x5F4C95AFC5EDC62EULL, 0x1DBC74446C07F0BDULL, 0xDAAD56789639AB08ULL, 0x985DB7933FD39D9BULL,
116 | 0x84193F60D72AF34FULL, 0xC6E9DE8B7EC0C5DCULL, 0x01F8FCB784FE9E69ULL, 0x43081D5C2D14A8FAULL,
117 | 0xCD2A5925D9681F90ULL, 0x8FDAB8CE70822903ULL, 0x48CB9AF28ABC72B6ULL, 0x0A3B7B1923564425ULL,
118 | 0x70428B155B4EAF1EULL, 0x32B26AFEF2A4998DULL, 0xF5A348C2089AC238ULL, 0xB753A929A170F4ABULL,
119 | 0x3971ED50550C43C1ULL, 0x7B810CBBFCE67552ULL, 0xBC902E8706D82EE7ULL, 0xFE60CF6CAF321874ULL,
120 | 0xE224479F47CB76A0ULL, 0xA0D4A674EE214033ULL, 0x67C58448141F1B86ULL, 0x253565A3BDF52D15ULL,
121 | 0xAB1721DA49899A7FULL, 0xE9E7C031E063ACECULL, 0x2EF6E20D1A5DF759ULL, 0x6C0603E6B3B7C1CAULL,
122 | 0xF6FAE5C07D3274CDULL, 0xB40A042BD4D8425EULL, 0x731B26172EE619EBULL, 0x31EBC7FC870C2F78ULL,
123 | 0xBFC9838573709812ULL, 0xFD39626EDA9AAE81ULL, 0x3A28405220A4F534ULL, 0x78D8A1B9894EC3A7ULL,
124 | 0x649C294A61B7AD73ULL, 0x266CC8A1C85D9BE0ULL, 0xE17DEA9D3263C055ULL, 0xA38D0B769B89F6C6ULL,
125 | 0x2DAF4F0F6FF541ACULL, 0x6F5FAEE4C61F773FULL, 0xA84E8CD83C212C8AULL, 0xEABE6D3395CB1A19ULL,
126 | 0x90C79D3FEDD3F122ULL, 0xD2377CD44439C7B1ULL, 0x15265EE8BE079C04ULL, 0x57D6BF0317EDAA97ULL,
127 | 0xD9F4FB7AE3911DFDULL, 0x9B041A914A7B2B6EULL, 0x5C1538ADB04570DBULL, 0x1EE5D94619AF4648ULL,
128 | 0x02A151B5F156289CULL, 0x4051B05E58BC1E0FULL, 0x87409262A28245BAULL, 0xC5B073890B687329ULL,
129 | 0x4B9237F0FF14C443ULL, 0x0962D61B56FEF2D0ULL, 0xCE73F427ACC0A965ULL, 0x8C8315CC052A9FF6ULL,
130 | 0x3A80143F5CF17F13ULL, 0x7870F5D4F51B4980ULL, 0xBF61D7E80F251235ULL, 0xFD913603A6CF24A6ULL,
131 | 0x73B3727A52B393CCULL, 0x31439391FB59A55FULL, 0xF652B1AD0167FEEAULL, 0xB4A25046A88DC879ULL,
132 | 0xA8E6D8B54074A6ADULL, 0xEA16395EE99E903EULL, 0x2D071B6213A0CB8BULL, 0x6FF7FA89BA4AFD18ULL,
133 | 0xE1D5BEF04E364A72ULL, 0xA3255F1BE7DC7CE1ULL, 0x64347D271DE22754ULL, 0x26C49CCCB40811C7ULL,
134 | 0x5CBD6CC0CC10FAFCULL, 0x1E4D8D2B65FACC6FULL, 0xD95CAF179FC497DAULL, 0x9BAC4EFC362EA149ULL,
135 | 0x158E0A85C2521623ULL, 0x577EEB6E6BB820B0ULL, 0x906FC95291867B05ULL, 0xD29F28B9386C4D96ULL,
136 | 0xCEDBA04AD0952342ULL, 0x8C2B41A1797F15D1ULL, 0x4B3A639D83414E64ULL, 0x09CA82762AAB78F7ULL,
137 | 0x87E8C60FDED7CF9DULL, 0xC51827E4773DF90EULL, 0x020905D88D03A2BBULL, 0x40F9E43324E99428ULL,
138 | 0x2CFFE7D5975E55E2ULL, 0x6E0F063E3EB46371ULL, 0xA91E2402C48A38C4ULL, 0xEBEEC5E96D600E57ULL,
139 | 0x65CC8190991CB93DULL, 0x273C607B30F68FAEULL, 0xE02D4247CAC8D41BULL, 0xA2DDA3AC6322E288ULL,
140 | 0xBE992B5F8BDB8C5CULL, 0xFC69CAB42231BACFULL, 0x3B78E888D80FE17AULL, 0x7988096371E5D7E9ULL,
141 | 0xF7AA4D1A85996083ULL, 0xB55AACF12C735610ULL, 0x724B8ECDD64D0DA5ULL, 0x30BB6F267FA73B36ULL,
142 | 0x4AC29F2A07BFD00DULL, 0x08327EC1AE55E69EULL, 0xCF235CFD546BBD2BULL, 0x8DD3BD16FD818BB8ULL,
143 | 0x03F1F96F09FD3CD2ULL, 0x41011884A0170A41ULL, 0x86103AB85A2951F4ULL, 0xC4E0DB53F3C36767ULL,
144 | 0xD8A453A01B3A09B3ULL, 0x9A54B24BB2D03F20ULL, 0x5D45907748EE6495ULL, 0x1FB5719CE1045206ULL,
145 | 0x919735E51578E56CULL, 0xD367D40EBC92D3FFULL, 0x1476F63246AC884AULL, 0x568617D9EF46BED9ULL,
146 | 0xE085162AB69D5E3CULL, 0xA275F7C11F7768AFULL, 0x6564D5FDE549331AULL, 0x279434164CA30589ULL,
147 | 0xA9B6706FB8DFB2E3ULL, 0xEB46918411358470ULL, 0x2C57B3B8EB0BDFC5ULL, 0x6EA7525342E1E956ULL,
148 | 0x72E3DAA0AA188782ULL, 0x30133B4B03F2B111ULL, 0xF7021977F9CCEAA4ULL, 0xB5F2F89C5026DC37ULL,
149 | 0x3BD0BCE5A45A6B5DULL, 0x79205D0E0DB05DCEULL, 0xBE317F32F78E067BULL, 0xFCC19ED95E6430E8ULL,
150 | 0x86B86ED5267CDBD3ULL, 0xC4488F3E8F96ED40ULL, 0x0359AD0275A8B6F5ULL, 0x41A94CE9DC428066ULL,
151 | 0xCF8B0890283E370CULL, 0x8D7BE97B81D4019FULL, 0x4A6ACB477BEA5A2AULL, 0x089A2AACD2006CB9ULL,
152 | 0x14DEA25F3AF9026DULL, 0x562E43B4931334FEULL, 0x913F6188692D6F4BULL, 0xD3CF8063C0C759D8ULL,
153 | 0x5DEDC41A34BBEEB2ULL, 0x1F1D25F19D51D821ULL, 0xD80C07CD676F8394ULL, 0x9AFCE626CE85B507ULL,
154 | };
155 |
156 | const unsigned char *pPtr = (const unsigned char *)pMem;
157 |
158 | std::uint64_t h;
159 |
160 | if( is_little_endian() )
161 | { h = my_hash[0] & 0xFFFFFFFF; h = ( (h << 32) | (my_hash[1] & 0xFFFFFFFF) ); }
162 | else
163 | { h = my_hash[1] & 0xFFFFFFFF; h = ( (h << 32) | (my_hash[0] & 0xFFFFFFFF) ); }
164 |
165 | h = ~h;
166 |
167 | while( iLen-- )
168 | {
169 | h = crcTable[ ( (h >> 56) ^ (*pPtr++) ) & 0xff ] ^ (h << 8);
170 | }
171 |
172 | h = ~h;
173 |
174 | if( is_little_endian() )
175 | return { basetype( ( h >> 32 ) & 0xFFFFFFFF ), basetype( h & 0xFFFFFFFF ) };
176 | else
177 | return { basetype( h & 0xFFFFFFFF ), basetype( ( h >> 32 ) & 0xFFFFFFFF ) };
178 | }
179 |
180 | // Generalized CRC (less collisions), Bob Jenkins
181 | static hash fGCRC( const void *pMem, size_t iLen, hash my_hash = { 0 } )
182 | {
183 | if( pMem == 0 || iLen == 0 ) return my_hash;
184 |
185 | static const basetype crcTable[256] =
186 | {
187 | 0x46D1E192,0x66EDF9AA,0x927FC9E5,0xA53BAACC,0x29B47658,0x5A411A01,0x0E66D5BD,
188 | 0x0DD5B1DB,0xCB38340E,0x04D4EBB6,0x98BC4F54,0x36F20F2C,0x4A3047ED,0x1EC1E0EB,
189 | 0x568C0C1F,0x6A731432,0x81367FC6,0xE3E25237,0xE7F64884,0x0FA59F64,0x4F3109DE,
190 | 0xF02D61F5,0x5DAEC03B,0x7F740E83,0x056FF2D8,0x2026CC0A,0x7AC2112D,0x82C55605,
191 | 0xB0911EF2,0xA7B88E4C,0x89DCA282,0x4B254D27,0x7694A6D3,0xD229EADD,0x8E8F3738,
192 | 0x5BEE7A55,0x012EB6AB,0x08DD28C8,0xB5ABC274,0xBC7931F0,0xF2396ED5,0xE4E43D97,
193 | 0x943F4B7F,0x85D0293D,0xAED83A88,0xC8F932FC,0xC5496F20,0xE9228173,0x9B465B7D,
194 | 0xFDA26680,0x1DDEAB35,0x0C4F25CB,0x86E32FAF,0xE59FA13A,0xE192E2C4,0xF147DA1A,
195 | 0x67620A8D,0x5C9A24C5,0xFE6AFDE2,0xACAD0250,0xD359730B,0xF35203B3,0x96A4B44D,
196 | 0xFBCACEA6,0x41A165EC,0xD71E53AC,0x835F39BF,0x6B6BDE7E,0xD07085BA,0x79064E07,
197 | 0xEE5B20C3,0x3B90BD65,0x5827AEF4,0x4D12D31C,0x9143496E,0x6C485976,0xD9552733,
198 | 0x220F6895,0xE69DEF19,0xEB89CD70,0xC9BB9644,0x93EC7E0D,0x2ACE3842,0x2B6158DA,
199 | 0x039E9178,0xBB5367D7,0x55682285,0x4315D891,0x19FD8906,0x7D8D4448,0xB4168A03,
200 | 0x40B56A53,0xAA3E69E0,0xA25182FE,0xAD34D16C,0x720C4171,0x9DC3B961,0x321DB563,
201 | 0x8B801B9E,0xF5971893,0x14CC1251,0x8F4AE962,0xF65AFF1E,0x13BD9DEE,0x5E7C78C7,
202 | 0xDDB61731,0x73832C15,0xEFEBDD5B,0x1F959ACA,0xE801FB22,0xA89826CE,0x30B7165D,
203 | 0x458A4077,0x24FEC52A,0x849B065F,0x3C6930CD,0xA199A81D,0xDB768F30,0x2E45C64A,
204 | 0xFF2F0D94,0x4EA97917,0x6F572ACF,0x653A195C,0x17A88C5A,0x27E11FB5,0x3F09C4C1,
205 | 0x2F87E71B,0xEA1493E4,0xD4B3A55E,0xBE6090BE,0xAF6CD9D9,0xDA58CA00,0x612B7034,
206 | 0x31711DAD,0x6D7DB041,0x8CA786B7,0x09E8BF7A,0xC3C4D7EA,0xA3CD77A8,0x7700F608,
207 | 0xDF3DE559,0x71C9353F,0x9FD236FB,0x1675D43E,0x390D9E9A,0x21BA4C6B,0xBD1371E8,
208 | 0x90338440,0xD5F163D2,0xB140FEF9,0x52F50B57,0x3710CF67,0x4C11A79C,0xC6D6624E,
209 | 0x3DC7AFA9,0x34A69969,0x70544A26,0xF7D9EC98,0x7C027496,0x1BFB3BA3,0xB3B1DC8F,
210 | 0x9A241039,0xF993F5A4,0x15786B99,0x26E704F7,0x51503C04,0x028BB3B8,0xEDE5600C,
211 | 0x9CB22B29,0xB6FF339B,0x7E771C43,0xC71C05F1,0x604CA924,0x695EED60,0x688ED0BC,
212 | 0x3E0B232F,0xF8A39C11,0xBAE6E67C,0xB8CF75E1,0x970321A7,0x5328922B,0xDEF3DF2E,
213 | 0x8D0443B0,0x2885E3AE,0x6435EED1,0xCC375E81,0xA98495F6,0xE0BFF114,0xB2DA3E4F,
214 | 0xC01B5ADF,0x507E0721,0x6267A36A,0x181A6DF8,0x7BAFF0C0,0xFA6D6C13,0x427250B2,
215 | 0xE2F742D6,0xCD5CC723,0x2D218BE7,0xB91FBBB1,0x9EB946D0,0x1C180810,0xFC81D602,
216 | 0x0B9C3F52,0xC2EA456F,0x1165B2C9,0xABF4AD75,0x0A56FC8C,0x12E0F818,0xCADBCBA1,
217 | 0x2586BE56,0x952C9B46,0x07C6A43C,0x78967DF3,0x477B2E49,0x2C5D7B6D,0x8A637272,
218 | 0x59ACBCB4,0x74A0E447,0xC1F8800F,0x35C015DC,0x230794C2,0x4405F328,0xEC2ADBA5,
219 | 0xD832B845,0x6E4ED287,0x48E9F7A2,0xA44BE89F,0x38CBB725,0xBF6EF4E6,0xDC0E83FA,
220 | 0x54238D12,0xF4F0C1E3,0xA60857FD,0xC43C64B9,0x00C851EF,0x33D75F36,0x5FD39866,
221 | 0xD1EFA08A,0xA0640089,0x877A978B,0x99175D86,0x57DFACBB,0xCEB02DE9,0xCF4D5C09,
222 | 0x3A8813D4,0xB7448816,0x63FA5568,0x06BE014B,0xD642FA7B,0x10AA7C90,0x8082C88E,
223 | 0x1AFCBA79,0x7519549D,0x490A87FF,0x8820C3A0
224 | };
225 |
226 | const unsigned char *pPtr = (const unsigned char *)pMem;
227 | basetype &h = my_hash[0];
228 |
229 | h ^= 0xFFFFFFFF;
230 |
231 | while( iLen-- )
232 | {
233 | h = (h >> 8) ^ crcTable[ (h ^ (*pPtr++)) & 0xFF ];
234 | }
235 |
236 | return { h ^ 0xFFFFFFFF };
237 | }
238 |
239 | // Robert Sedgwicks
240 | static hash fRS( const void *pMem, size_t iLen, hash my_hash = { 0 } )
241 | {
242 | if( pMem == 0 || iLen == 0 ) return my_hash;
243 |
244 | const unsigned char *pPtr = (const unsigned char *)pMem;
245 | basetype &h = my_hash[0];
246 |
247 | basetype b = 378551;
248 | basetype a = 63689;
249 |
250 | while( iLen-- )
251 | {
252 | h = h * a + ((basetype) (*pPtr++));
253 | a = a * b;
254 | }
255 |
256 | return my_hash;
257 | }
258 |
259 | // Justin Sobel
260 | static hash fJS( const void *pMem, size_t iLen, hash my_hash = { 1315423911 } )
261 | {
262 | if( pMem == 0 || iLen == 0 ) return my_hash;
263 |
264 | const unsigned char *pPtr = (const unsigned char *)pMem;
265 | basetype &h = my_hash[0];
266 |
267 | while( iLen-- )
268 | {
269 | h ^= ((h << 5) + ((basetype) (*pPtr++)) + (h >> 2));
270 | }
271 |
272 | return my_hash;
273 | }
274 |
275 | // P. J. Weinberger
276 | static hash fPJW( const void *pMem, size_t iLen, hash my_hash = { 0 } )
277 | {
278 | if( pMem == 0 || iLen == 0 ) return my_hash;
279 |
280 | const unsigned char *pPtr = (const unsigned char *)pMem;
281 | basetype &h = my_hash[0];
282 |
283 | basetype BitsInUnsignedInt = (basetype)(sizeof(basetype) * 8);
284 | basetype ThreeQuarters = (basetype)((BitsInUnsignedInt * 3) / 4);
285 | basetype OneEighth = (basetype)(BitsInUnsignedInt / 8);
286 | basetype HighBits = (basetype)(0xFFFFFFFF) << (BitsInUnsignedInt - OneEighth);
287 | basetype test = 0;
288 |
289 | while( iLen-- )
290 | {
291 | h = (h << OneEighth) + ((basetype) (*pPtr++));
292 |
293 | if((test = h & HighBits) != 0)
294 | {
295 | h = (( h ^ (test >> ThreeQuarters)) & (~HighBits));
296 | }
297 | }
298 |
299 | return my_hash;
300 | }
301 |
302 | // Tweaked PJW for 32-bit
303 | static hash fELF( const void *pMem, size_t iLen, hash my_hash = { 0 } )
304 | {
305 | if( pMem == 0 || iLen == 0 ) return my_hash;
306 |
307 | const unsigned char *pPtr = (const unsigned char *)pMem;
308 | basetype &h = my_hash[0];
309 |
310 | basetype x = 0;
311 |
312 | while( iLen-- )
313 | {
314 | h = (h << 4) + ((basetype) (*pPtr++));
315 | if((x = h & 0xF0000000L) != 0)
316 | {
317 | h ^= (x >> 24);
318 | }
319 | h &= ~x;
320 | }
321 |
322 | return my_hash;
323 | }
324 |
325 | // Brian Kernighan and Dennis Ritchie
326 | static hash fBKDR( const void *pMem, size_t iLen, hash my_hash = { 0 } )
327 | {
328 | if( pMem == 0 || iLen == 0 ) return my_hash;
329 |
330 | const unsigned char *pPtr = (const unsigned char *)pMem;
331 | basetype &h = my_hash[0];
332 |
333 | const basetype seed_ = 131; // 31 131 1313 13131 131313 etc..
334 |
335 | while( iLen-- )
336 | {
337 | h = (h * seed_) + ((basetype) (*pPtr++));
338 | }
339 |
340 | return my_hash;
341 | }
342 |
343 | // Open source SDBM project
344 | static hash fSDBM( const void *pMem, size_t iLen, hash my_hash = { 0 } )
345 | {
346 | if( pMem == 0 || iLen == 0 ) return my_hash;
347 |
348 | const unsigned char *pPtr = (const unsigned char *)pMem;
349 | basetype &h = my_hash[0];
350 |
351 | while( iLen-- )
352 | {
353 | h = ((basetype) (*pPtr++)) + (h << 6) + (h << 16) - h;
354 | }
355 |
356 | return my_hash;
357 | }
358 |
359 | // Daniel J. Bernstein
360 | static hash fDJB( const void *pMem, size_t iLen, hash my_hash = { 5381 } ) //seed=0
361 | {
362 | if( pMem == 0 || iLen == 0 ) return my_hash;
363 |
364 | const unsigned char *pPtr = (const unsigned char *)pMem;
365 | basetype &h = my_hash[0];
366 |
367 | while( iLen-- )
368 | {
369 | h = ((h << 5) + h) + ((basetype) (*pPtr++));
370 | }
371 |
372 | return my_hash;
373 | }
374 |
375 | // Daniel J. Bernstein (2)
376 | static hash fDJB2( const void *pMem, size_t iLen, hash my_hash = { 5381 } ) //seed=0
377 | {
378 | if( pMem == 0 || iLen == 0 ) return my_hash;
379 |
380 | const unsigned char *pPtr = (const unsigned char *)pMem;
381 | basetype &h = my_hash[0];
382 |
383 | while( iLen-- )
384 | {
385 | h = ((h << 5) + h) ^ ((basetype) (*pPtr++));
386 | }
387 |
388 | return my_hash;
389 | }
390 |
391 | // ?
392 | static hash fBP( const void *pMem, size_t iLen, hash my_hash = { 0 } )
393 | {
394 | if( pMem == 0 || iLen == 0 ) return my_hash;
395 |
396 | const unsigned char *pPtr = (const unsigned char *)pMem;
397 | basetype &h = my_hash[0];
398 |
399 | while( iLen-- )
400 | {
401 | h = h << 7 ^ ((basetype) (*pPtr++));
402 | }
403 |
404 | return my_hash;
405 | }
406 |
407 | // Fowler-Noll-Vo
408 | static hash fFNV( const void *pMem, size_t iLen, hash my_hash = { 0x811C9DC5 } )
409 | {
410 | if( pMem == 0 || iLen == 0 ) return my_hash;
411 |
412 | const unsigned char *pPtr = (const unsigned char *)pMem;
413 | basetype &h = my_hash[0];
414 |
415 | const basetype fnv_prime = 0x1000193;
416 |
417 | while( iLen-- )
418 | {
419 | h *= fnv_prime;
420 | h ^= ((basetype) (*pPtr++));
421 | }
422 |
423 | return my_hash;
424 | }
425 |
426 | // Fowler-Noll-Vo-1a
427 | static hash fFNV1a( const void *pMem, size_t iLen, hash my_hash = { 0x811C9DC5 } )
428 | {
429 | if( pMem == 0 || iLen == 0 ) return my_hash;
430 |
431 | const unsigned char *pPtr = (const unsigned char *)pMem;
432 | basetype &h = my_hash[0];
433 |
434 | const basetype fnv_prime = 0x1000193;
435 |
436 | while( iLen-- )
437 | {
438 | h ^= ((basetype) (*pPtr++));
439 | h *= fnv_prime;
440 | }
441 |
442 | return my_hash;
443 | }
444 |
445 | // Arash Partow
446 | static hash fAP( const void *pMem, size_t iLen, hash my_hash = { 0xAAAAAAAA } )
447 | {
448 | if( pMem == 0 || iLen == 0 ) return my_hash;
449 |
450 | const unsigned char *pPtr = (const unsigned char *)pMem;
451 | basetype &h = my_hash[0];
452 |
453 | for( size_t i = 0; i < iLen; i++ )
454 | {
455 | h ^= ((i & 1) == 0) ? ( (h << 7) ^ ((basetype) (*pPtr++)) * (h >> 3)) :
456 | (~((h << 11) + ((basetype) (*pPtr++)) ^ (h >> 5)));
457 | }
458 |
459 | return my_hash;
460 | }
461 |
462 | // Bob Jenkins (one-at-a-time)
463 | static hash fBJ1( const void *pMem, size_t iLen, hash my_hash = { 0 } )
464 | {
465 | if( pMem == 0 || iLen == 0 ) return my_hash;
466 |
467 | const unsigned char *pPtr = (const unsigned char *)pMem;
468 | basetype &h = my_hash[0];
469 |
470 | while( iLen-- )
471 | {
472 | h += ((basetype) (*pPtr++));
473 | h += (h << 10);
474 | h ^= (h >> 6);
475 | }
476 |
477 | h += (h << 3);
478 | h ^= (h >> 11);
479 | h += (h << 15);
480 |
481 | return my_hash;
482 | }
483 |
484 | // Murmurmy_Hash2 by Austin Appleby
485 | static hash fMH2( const void *pMem, size_t iLen, hash my_hash = { 0 } )
486 | {
487 | if( pMem == 0 || iLen == 0 ) return my_hash;
488 |
489 | const basetype m = 0x5bd1e995;
490 | const int r = 24;
491 |
492 | basetype h = my_hash[0] ^ ((basetype)iLen);
493 |
494 | const unsigned char *data = (const unsigned char *)pMem;
495 |
496 | while(iLen >= 4)
497 | {
498 | basetype k;
499 |
500 | k = data[0];
501 | k |= data[1] << 8;
502 | k |= data[2] << 16;
503 | k |= data[3] << 24;
504 |
505 | k *= m;
506 | k ^= k >> r;
507 | k *= m;
508 |
509 | h *= m;
510 | h ^= k;
511 |
512 | data += 4;
513 | iLen -= 4;
514 | }
515 |
516 | switch(iLen)
517 | {
518 | case 3: h ^= data[2] << 16;
519 | case 2: h ^= data[1] << 8;
520 | case 1: h ^= data[0];
521 | h *= m;
522 | };
523 |
524 | h ^= h >> 13;
525 | h *= m;
526 | h ^= h >> 15;
527 |
528 | return { h };
529 | }
530 |
531 | // SuperFastHash by Paul Hsieh
532 | static hash fSFH( const void *pMem, size_t iLen, hash my_hash = hash { 0 } )
533 | {
534 | if( pMem == 0 || iLen == 0 ) return my_hash;
535 |
536 | # undef get16bits
537 | # if (defined(__GNUC__) && defined(__i386__)) || defined(__WATCOMC__) \
538 | || defined(_MSC_VER) || defined (__BORLANDC__) || defined (__TURBOC__)
539 | # define get16bits(d) (*((const uint16_t *) (d)))
540 | # else
541 | # define get16bits(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
542 | +(uint32_t)(((const uint8_t *)(d))[0]) )
543 | # endif
544 |
545 | std::uint32_t tmp;
546 | int rem;
547 |
548 | rem = iLen & 3;
549 | iLen >>= 2;
550 |
551 | const char * data = (const char *)pMem;
552 | basetype &h = my_hash[0];
553 |
554 | /* Main loop */
555 | for (;iLen > 0; iLen--) {
556 | h += get16bits (data);
557 | tmp = (get16bits (data+2) << 11) ^ h;
558 | h = (h << 16) ^ tmp;
559 | data += 2*sizeof (uint16_t);
560 | h += h >> 11;
561 | }
562 |
563 | /* Handle end cases */
564 | switch (rem) { default:
565 | case 3: h += get16bits (data);
566 | h ^= h << 16;
567 | h ^= ((signed char)data[sizeof (uint16_t)]) << 18;
568 | h += h >> 11;
569 | break;
570 | case 2: h += get16bits (data);
571 | h ^= h << 11;
572 | h += h >> 17;
573 | break;
574 | case 1: h += (signed char)*data;
575 | h ^= h << 10;
576 | h += h >> 1;
577 | }
578 |
579 | /* Force "avalanching" of final 127 bits */
580 | h ^= h << 3;
581 | h += h >> 5;
582 | h ^= h << 4;
583 | h += h >> 17;
584 | h ^= h << 25;
585 | h += h >> 6;
586 |
587 | return { h };
588 |
589 | # undef get16bits
590 | }
591 |
592 | // Mostly based on Paul E. Jones' sha1 implementation
593 | static hash fSHA1( const void *pMem, size_t iLen, hash my_hash = hash{ 0x67452301,0xEFCDAB89,0x98BADCFE,0x10325476,0xC3D2E1F0 } )
594 | {
595 | // if( pMem == 0 || iLen == 0 ) return my_hash;
596 |
597 | struct Process
598 | {
599 | static basetype CircularShift(int bits, basetype word)
600 | {
601 | return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32-bits));
602 | }
603 |
604 | static void MessageBlock( hash &H, unsigned char *Message_Block, int &Message_Block_Index )
605 | {
606 | const basetype K[] = { // Constants defined for SHA-1
607 | 0x5A827999,
608 | 0x6ED9EBA1,
609 | 0x8F1BBCDC,
610 | 0xCA62C1D6
611 | };
612 | int t; // Loop counter
613 | basetype temp; // Temporary word value
614 | basetype W[80]; // Word sequence
615 | basetype A, B, C, D, E; // Word buffers
616 |
617 | /*
618 | * Initialize the first 16 words in the array W
619 | */
620 | for(t = 0; t < 16; t++)
621 | {
622 | W[t] = ((basetype) Message_Block[t * 4]) << 24;
623 | W[t] |= ((basetype) Message_Block[t * 4 + 1]) << 16;
624 | W[t] |= ((basetype) Message_Block[t * 4 + 2]) << 8;
625 | W[t] |= ((basetype) Message_Block[t * 4 + 3]);
626 | }
627 |
628 | for(t = 16; t < 80; t++)
629 | {
630 | W[t] = CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
631 | }
632 |
633 | A = H[0];
634 | B = H[1];
635 | C = H[2];
636 | D = H[3];
637 | E = H[4];
638 |
639 | for(t = 0; t < 20; t++)
640 | {
641 | temp = CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0]; //D^(B&(C^D))
642 | temp &= 0xFFFFFFFF;
643 | E = D;
644 | D = C;
645 | C = CircularShift(30,B);
646 | B = A;
647 | A = temp;
648 | }
649 |
650 | for(t = 20; t < 40; t++)
651 | {
652 | temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
653 | temp &= 0xFFFFFFFF;
654 | E = D;
655 | D = C;
656 | C = CircularShift(30,B);
657 | B = A;
658 | A = temp;
659 | }
660 |
661 | for(t = 40; t < 60; t++)
662 | {
663 | temp = CircularShift(5,A) +
664 | ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2]; //(B & C) | (D & (B | C))
665 | temp &= 0xFFFFFFFF;
666 | E = D;
667 | D = C;
668 | C = CircularShift(30,B);
669 | B = A;
670 | A = temp;
671 | }
672 |
673 | for(t = 60; t < 80; t++)
674 | {
675 | temp = CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
676 | temp &= 0xFFFFFFFF;
677 | E = D;
678 | D = C;
679 | C = CircularShift(30,B);
680 | B = A;
681 | A = temp;
682 | }
683 |
684 | H[0] = (H[0] + A) & 0xFFFFFFFF;
685 | H[1] = (H[1] + B) & 0xFFFFFFFF;
686 | H[2] = (H[2] + C) & 0xFFFFFFFF;
687 | H[3] = (H[3] + D) & 0xFFFFFFFF;
688 | H[4] = (H[4] + E) & 0xFFFFFFFF;
689 |
690 | Message_Block_Index = 0;
691 | }
692 | };
693 |
694 | // 512-bit message blocks
695 | unsigned char Message_Block[64];
696 | // Index into message block array
697 | int Message_Block_Index = 0;
698 | // Message length in bits
699 | basetype Length_Low = 0, Length_High = 0;
700 |
701 | if( iLen > 0 )
702 | {
703 | // Is the message digest corrupted?
704 | bool Corrupted = false;
705 |
706 | // Input()
707 |
708 | unsigned char *message_array = (unsigned char *)pMem;
709 |
710 | while(iLen-- && !Corrupted)
711 | {
712 | Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
713 |
714 | Length_Low += 8;
715 | Length_Low &= 0xFFFFFFFF; // Force it to 32 bits
716 | if (Length_Low == 0)
717 | {
718 | Length_High++;
719 | Length_High &= 0xFFFFFFFF; // Force it to 32 bits
720 | if (Length_High == 0)
721 | {
722 | Corrupted = true; // Message is too long
723 | }
724 | }
725 |
726 | if (Message_Block_Index == 64)
727 | {
728 | Process::MessageBlock( my_hash, Message_Block, Message_Block_Index );
729 | }
730 |
731 | message_array++;
732 | }
733 |
734 | assert( !Corrupted );
735 | }
736 |
737 | // Result() and PadMessage()
738 |
739 | /*
740 | * Check to see if the current message block is too small to hold
741 | * the initial padding bits and length. If so, we will pad the
742 | * block, process it, and then continue padding into a second block.
743 | */
744 | if (Message_Block_Index > 55)
745 | {
746 | Message_Block[Message_Block_Index++] = 0x80;
747 |
748 | while(Message_Block_Index < 64)
749 | {
750 | Message_Block[Message_Block_Index++] = 0;
751 | }
752 |
753 | Process::MessageBlock( my_hash, Message_Block, Message_Block_Index );
754 |
755 | while(Message_Block_Index < 56)
756 | {
757 | Message_Block[Message_Block_Index++] = 0;
758 | }
759 | }
760 | else
761 | {
762 | Message_Block[Message_Block_Index++] = 0x80;
763 |
764 | while(Message_Block_Index < 56)
765 | {
766 | Message_Block[Message_Block_Index++] = 0;
767 | }
768 | }
769 |
770 | /*
771 | * Store the message length as the last 8 octets
772 | */
773 | Message_Block[56] = (Length_High >> 24) & 0xFF;
774 | Message_Block[57] = (Length_High >> 16) & 0xFF;
775 | Message_Block[58] = (Length_High >> 8) & 0xFF;
776 | Message_Block[59] = (Length_High) & 0xFF;
777 | Message_Block[60] = (Length_Low >> 24) & 0xFF;
778 | Message_Block[61] = (Length_Low >> 16) & 0xFF;
779 | Message_Block[62] = (Length_Low >> 8) & 0xFF;
780 | Message_Block[63] = (Length_Low) & 0xFF;
781 |
782 | Process::MessageBlock( my_hash, Message_Block, Message_Block_Index );
783 |
784 | return my_hash;
785 | }
786 |
787 | // general interface
788 |
789 | static hash any( int FN, hash &h, const void *ptr, size_t len ) {
790 | /**/ if( FN == use::CRC32 ) return h = cocoa::use::fCRC32(ptr, len, h);
791 | else if( FN == use::CRC64 ) return h = cocoa::use::fCRC64(ptr, len, h);
792 | else if( FN == use::GCRC ) return h = cocoa::use::fGCRC(ptr, len, h);
793 | else if( FN == use::RS ) return h = cocoa::use::fRS(ptr, len, h);
794 | else if( FN == use::JS ) return h = cocoa::use::fJS(ptr, len, h);
795 | else if( FN == use::PJW ) return h = cocoa::use::fPJW(ptr, len, h);
796 | else if( FN == use::ELF ) return h = cocoa::use::fELF(ptr, len, h);
797 | else if( FN == use::BKDR ) return h = cocoa::use::fBKDR(ptr, len, h);
798 | else if( FN == use::SDBM ) return h = cocoa::use::fSDBM(ptr, len, h);
799 | else if( FN == use::DJB ) return h = cocoa::use::fDJB(ptr, len, h);
800 | else if( FN == use::DJB2 ) return h = cocoa::use::fDJB2(ptr, len, h);
801 | else if( FN == use::BP ) return h = cocoa::use::fBP(ptr, len, h);
802 | else if( FN == use::FNV ) return h = cocoa::use::fFNV(ptr, len, h);
803 | else if( FN == use::FNV1a ) return h = cocoa::use::fFNV1a(ptr, len, h);
804 | else if( FN == use::AP ) return h = cocoa::use::fAP(ptr, len, h);
805 | else if( FN == use::BJ1 ) return h = cocoa::use::fBJ1(ptr, len, h);
806 | else if( FN == use::MH2 ) return h = cocoa::use::fMH2(ptr, len, h);
807 | else if( FN == use::SHA1 ) return h = cocoa::use::fSHA1(ptr, len, h);
808 | else if( FN == use::SFH ) return h = cocoa::use::fSFH(ptr, len, h);
809 | return h;
810 | }
811 | };
812 |
813 | template
814 | class hash
815 | {
816 | std::vector h;
817 |
818 | public:
819 |
820 | hash() : h( 1, 0 ) {
821 | /**/ if( FN == cocoa::use::DJB) h[0] = 5381;
822 | else if( FN == cocoa::use::DJB2) h[0] = 5381;
823 | else if( FN == cocoa::use::FNV) h[0] = 0x811C9DC5;
824 | else if( FN == cocoa::use::FNV1a) h[0] = 0x811C9DC5;
825 | else if( FN == cocoa::use::AP) h[0] = 0xAAAAAAAA;
826 | else if( FN == cocoa::use::CRC64) h = { 0, 0 };
827 | else if( FN == cocoa::use::SHA1) h = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };
828 | }
829 |
830 | inline basetype &operator []( basetype i )
831 | {
832 | return h[i];
833 | }
834 | inline const basetype &operator []( basetype i ) const
835 | {
836 | return h[i];
837 | }
838 |
839 | inline bool operator ==( const hash &t ) const
840 | {
841 | return h == t.h;
842 | }
843 |
844 | inline bool operator !=( const hash &t ) const
845 | {
846 | return h != t.h;
847 | }
848 |
849 | inline bool operator<( const hash &t ) const
850 | {
851 | return h < t.h;
852 | }
853 |
854 | inline bool operator ==( const std::string &t ) const
855 | {
856 | return str() == t;
857 | }
858 |
859 | inline const bool operator<( const std::string &t ) const
860 | {
861 | return str() < t;
862 | }
863 |
864 | size_t size() const
865 | {
866 | return h.size();
867 | }
868 |
869 | const void *data() const
870 | {
871 | return h.data();
872 | }
873 |
874 | void *data()
875 | {
876 | return h.data();
877 | }
878 |
879 | std::vector::iterator begin() { return h.begin(); }
880 | std::vector::iterator end() { return h.end(); }
881 | std::vector::const_iterator begin() const { return h.begin(); }
882 | std::vector::const_iterator end() const { return h.end(); }
883 |
884 | operator std::string() const
885 | {
886 | return str();
887 | }
888 |
889 | std::string str() const
890 | {
891 | std::string out;
892 |
893 | for( std::vector::const_iterator it = h.begin(); it != h.end(); ++it )
894 | {
895 | std::stringstream ss;
896 | std::string s;
897 | ss << std::hex << std::setfill('0') << std::setw(8) << (*it);
898 | ss >> s;
899 | out += s;
900 | }
901 |
902 | return out;
903 | }
904 |
905 | std::vector blob() const
906 | {
907 | std::vector blob;
908 |
909 | if( use::is_big_endian() )
910 | for( std::vector::const_iterator it = h.begin(); it != h.end(); ++it )
911 | for( unsigned i = 0; i < sizeof(basetype); ++i )
912 | blob.push_back( ( (*it) >> (i * 8) ) & 0xff );
913 | else
914 | for( std::vector::const_iterator it = h.begin(); it != h.end(); ++it )
915 | for( unsigned i = sizeof(basetype); i-- > 0; )
916 | blob.push_back( ( (*it) >> (i * 8) ) & 0xff );
917 |
918 | return blob;
919 | }
920 |
921 | public:
922 |
923 | // ostream
924 |
925 | template
926 | inline friend ostream &operator<<( ostream &os, const hash &self )
927 | {
928 | return (os << self.str()), os;
929 | }
930 |
931 | // chain hasher
932 |
933 | template
934 | hash operator()( const T &input ) const {
935 | hash self = *this;
936 | return self.h = use::any( FN, self.h, input.data(), input.size() * sizeof( *input.begin() ) ), self;
937 | }
938 |
939 | hash operator()( const char *input = (const char *)0 ) const {
940 | hash self = *this;
941 | return self.h = use::any( FN, self.h, input, input ? std::strlen(input) : 0 ), self;
942 | }
943 | hash operator()( const char &input ) const {
944 | hash self = *this;
945 | return self.h = use::any( FN, self.h, &input, sizeof(input) ), self;
946 | }
947 | hash operator()( const int &input ) const {
948 | hash self = *this;
949 | return self.h = use::any( FN, self.h, &input, sizeof(input) ), self;
950 | }
951 | hash operator()( const size_t &input ) const {
952 | hash self = *this;
953 | return self.h = use::any( FN, self.h, &input, sizeof(input) ), self;
954 | }
955 | hash operator()( const float &input ) const {
956 | hash self = *this;
957 | return self.h = use::any( FN, self.h, &input, sizeof(input) ), self;
958 | }
959 | hash operator()( const double &input ) const {
960 | hash self = *this;
961 | return self.h = use::any( FN, self.h, &input, sizeof(input) ), self;
962 | }
963 |
964 | template
965 | hash operator()(const T &value, Args... args) const {
966 | hash self = *this;
967 | self.operator()( value );
968 | self.operator()(args...);
969 | return self;
970 | }
971 |
972 | };
973 | }
974 |
975 | namespace cocoa
976 | {
977 | template< typename T >
978 | inline hash CRC32( const T &input, const hash &my_hash = hash() ) {
979 | return my_hash.operator()( input );
980 | }
981 | template< typename T >
982 | inline hash CRC64( const T &input, const hash &my_hash = hash() ) {
983 | return my_hash.operator()( input );
984 | }
985 | template< typename T >
986 | inline hash GCRC( const T &input, const hash &my_hash = hash() ) {
987 | return my_hash.operator()( input );
988 | }
989 | template< typename T >
990 | inline hash RS( const T &input, const hash &my_hash = hash() ) {
991 | return my_hash.operator()( input );
992 | }
993 | template< typename T >
994 | inline hash JS( const T &input, const hash &my_hash = hash() ) {
995 | return my_hash.operator()( input );
996 | }
997 | template< typename T >
998 | inline hash PJW( const T &input, const hash &my_hash = hash() ) {
999 | return my_hash.operator()( input );
1000 | }
1001 | template< typename T >
1002 | inline hash ELF( const T &input, const hash &my_hash = hash() ) {
1003 | return my_hash.operator()( input );
1004 | }
1005 | template< typename T >
1006 | inline hash BKDR( const T &input, const hash &my_hash = hash() ) {
1007 | return my_hash.operator()( input );
1008 | }
1009 | template< typename T >
1010 | inline hash SDBM( const T &input, const hash &my_hash = hash() ) {
1011 | return my_hash.operator()( input );
1012 | }
1013 | template< typename T >
1014 | inline hash DJB( const T &input, const hash &my_hash = hash() ) {
1015 | return my_hash.operator()( input );
1016 | }
1017 | template< typename T >
1018 | inline hash DJB2( const T &input, const hash &my_hash = hash() ) {
1019 | return my_hash.operator()( input );
1020 | }
1021 | template< typename T >
1022 | inline hash BP( const T &input, const hash &my_hash = hash() ) {
1023 | return my_hash.operator()( input );
1024 | }
1025 | template< typename T >
1026 | inline hash FNV( const T &input, const hash &my_hash = hash() ) {
1027 | return my_hash.operator()( input );
1028 | }
1029 | template< typename T >
1030 | inline hash FNV1a( const T &input, const hash &my_hash = hash() ) {
1031 | return my_hash.operator()( input );
1032 | }
1033 | template< typename T >
1034 | inline hash AP( const T &input, const hash &my_hash = hash() ) {
1035 | return my_hash.operator()( input );
1036 | }
1037 | template< typename T >
1038 | inline hash BJ1( const T &input, const hash &my_hash = hash() ) {
1039 | return my_hash.operator()( input );
1040 | }
1041 | template< typename T >
1042 | inline hash MH2( const T &input, const hash &my_hash = hash() ) {
1043 | return my_hash.operator()( input );
1044 | }
1045 | template< typename T >
1046 | inline hash SHA1( const T &input, const hash &my_hash = hash() ) {
1047 | return my_hash.operator()( input );
1048 | }
1049 | template< typename T >
1050 | inline hash SFH( const T &input, const hash &my_hash = hash() ) {
1051 | return my_hash.operator()( input );
1052 | }
1053 | }
1054 |
--------------------------------------------------------------------------------
/sample.cc:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include "cocoa.hpp"
5 |
6 | int main() {
7 | std::string hash = cocoa::SHA1("hello world");
8 | std::cout << hash << std::endl;
9 | assert( cocoa::SHA1("hello world") == cocoa::SHA1("hello world") );
10 | return 0;
11 | }
12 |
--------------------------------------------------------------------------------
/tests.cxx:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | #include
4 | #include
5 |
6 | #include "cocoa.hpp"
7 |
8 |
9 |
10 | int main( int argc, const char **argv )
11 | {
12 | std::string key = "abcdefghijklmnopqrstuvwxyz1234567890";
13 |
14 | std::cout << "General Purpose Hash Function Algorithms Test" << std::endl;
15 | std::cout << " 1. RS-Hash Function Value: " << cocoa::RS( key ) << std::endl;
16 | std::cout << " 2. JS-Hash Function Value: " << cocoa::JS( key ) << std::endl;
17 | std::cout << " 3. PJW-Hash Function Value: " << cocoa::PJW( key ) << std::endl;
18 | std::cout << " 4. ELF-Hash Function Value: " << cocoa::ELF( key ) << std::endl;
19 | std::cout << " 5. BKDR-Hash Function Value: " << cocoa::BKDR( key ) << std::endl;
20 | std::cout << " 6. SDBM-Hash Function Value: " << cocoa::SDBM( key ) << std::endl;
21 | std::cout << " 7. DJB-Hash Function Value: " << cocoa::DJB( key ) << std::endl;
22 | std::cout << " 8. FNV-Hash Function Value: " << cocoa::FNV( key ) << std::endl;
23 | std::cout << " 9. FNV1a-Hash Function Value: " << cocoa::FNV1a( key ) << std::endl;
24 | std::cout << "10. BP-Hash Function Value: " << cocoa::BP( key ) << std::endl;
25 | std::cout << "11. AP-Hash Function Value: " << cocoa::AP( key ) << std::endl;
26 | std::cout << "12. CRC32-Hash Function Value: " << cocoa::CRC32( key ) << std::endl;
27 | std::cout << "13. CRC64-Hash Function Value: " << cocoa::CRC64( key ) << std::endl;
28 | std::cout << "14. MH2-Hash Function Value: " << cocoa::MH2( key ) << std::endl;
29 | std::cout << "15. BJ1-Hash Function Value: " << cocoa::BJ1( key ) << std::endl;
30 | std::cout << "16. CRC-Hash Function Value: " << cocoa::GCRC( key ) << std::endl;
31 | std::cout << "17. SHA1-Hash Function Value: " << cocoa::SHA1( key ) << std::endl;
32 | std::cout << "18. SFH-Hash Function Value: " << cocoa::SFH( key ) << std::endl;
33 |
34 | // a few tests from http://www.nitrxgen.net/hashgen/ (thanks guys!)
35 | assert( cocoa::CRC32("hello world").blob().size() == 4 );
36 | assert( cocoa::CRC32("hello world") == "0d4a1185" );
37 | assert( cocoa::CRC32("world", cocoa::CRC32("hello ")) == "0d4a1185" );
38 | assert( cocoa::CRC32("hello world") == cocoa::CRC32("hello world") );
39 |
40 | assert( cocoa::CRC64("hello world").blob().size() == 8 );
41 | assert( cocoa::CRC64("hello world") == "c287020321943b9d" );
42 | assert( cocoa::CRC64("world", cocoa::CRC64("hello ")) == "c287020321943b9d" );
43 | assert( cocoa::CRC64("hello world") == cocoa::CRC64("hello world") );
44 |
45 | assert( cocoa::SHA1("hello world").blob().size() == 20 );
46 | assert( cocoa::SHA1("hello world") == "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" );
47 | //@todo: fixme (terminator issue). will help MD5 too
48 | //assert( cocoa::SHA1("world", cocoa::SHA1("hello ")) == "2aae6c35c94fcfb415dbe95f408b9ce91ee846ed" );
49 | assert( cocoa::SHA1("hello world") == cocoa::SHA1("hello world") );
50 |
51 | assert( cocoa::SHA1("") == "da39a3ee5e6b4b0d3255bfef95601890afd80709" );
52 | assert( cocoa::CRC32("") == "00000000" );
53 | assert( cocoa::CRC64("") == "0000000000000000" );
54 |
55 |
56 | std::cout << cocoa::hash()(123)("abc")(3.14159f).str() << std::endl;
57 | std::cout << cocoa::hash()(123, "abc", 3.14159f).str() << std::endl;
58 |
59 | std::cout << "All ok." << std::endl;
60 |
61 | return 0;
62 | }
63 |
--------------------------------------------------------------------------------