├── .travis.yml ├── LICENSE ├── README.md ├── cocoa.cpp ├── cocoa.hpp ├── sample.cc └── tests.cxx /.travis.yml: -------------------------------------------------------------------------------- 1 | language: cpp 2 | 3 | compiler: 4 | - clang 5 | - gcc 6 | 7 | install: 8 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.pre.sh | bash -x 9 | 10 | script: 11 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.build.sh | bash -x 12 | - wget --quiet -O - https://raw.githubusercontent.com/r-lyeh/depot/master/travis.run.sh | bash -x 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 r-lyeh (https://github.com/r-lyeh) 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | cocoa 2 | ===== 3 | 4 | - Cocoa is an uniform hashing library written in C++11. 5 | - Cocoa provides interface for CRC32, CRC64, GCRC, RS, JS, PJW, ELF, BKDR, SBDM, DJB, DJB2, BP, FNV, FNV1a, AP, BJ1, MH2, SHA1, SFH. 6 | - Cocoa is tiny. Header-only. 7 | - Cocoa is cross-platform. No dependencies. 8 | - Cocoa is zlib/libpng licensed. 9 | 10 | ### Sample 11 | ```c++ 12 | #include 13 | #include 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 | --------------------------------------------------------------------------------