README | 2 +
src/base/Makefile.am | 18 ++++--
src/base/hash.cc | 28 +++++++++++
src/base/hash.h | 67 +++++++++++++++++++++++++++
src/base/tests/hash_test.cc | 109 ++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 217 insertions(+), 7 deletions(-)
Add a function that takes a string as input and returns another string which is
a hash of the input string generated using a collision-resistant hash function.
diff --git a/README b/README
--- a/README
+++ b/README
@@ -425,6 +425,7 @@ The following software is required to bu
* libc6-dev (2.11 or later)
* libxml2-dev (2.7 or later)
+ * libssl-dev (0.9.8 or later)
* automake (1.11.1 or later)
* m4
* autoconf (2.64 or later)
@@ -959,6 +960,7 @@ minimum version requirements of the foll
- GNU C Library (Glibc), version 2.11 or later
- GNU Compiler Collection (GCC), version 4.8.1 or later
- Libxml2, version 2.7 or later
+- Libopenssl, version 0.9.8 or later
- Libsqlite3, version 3.6 or later (only needed when configuring with
--enable-imm-pbe)
- OpenHPI, version 2.17.0 or later (only needed when configuring with
diff --git a/src/base/Makefile.am b/src/base/Makefile.am
--- a/src/base/Makefile.am
+++ b/src/base/Makefile.am
@@ -37,6 +37,7 @@ lib_libopensaf_core_la_SOURCES += \
src/base/file_descriptor.cc \
src/base/file_notify.cc \
src/base/getenv.cc \
+ src/base/hash.cc \
src/base/hj_dec.c \
src/base/hj_edp.c \
src/base/hj_edu.c \
@@ -83,6 +84,7 @@ noinst_HEADERS += \
src/base/file_descriptor.h \
src/base/file_notify.h \
src/base/getenv.h \
+ src/base/hash.h \
src/base/log_message.h \
src/base/logtrace.h \
src/base/macros.h \
@@ -180,17 +182,19 @@ bin_libbase_test_CPPFLAGS = \
bin_libbase_test_LDFLAGS = \
$(AM_LDFLAGS) \
- src/base/lib_libopensaf_core_la-unix_socket.lo \
- src/base/lib_libopensaf_core_la-unix_server_socket.lo \
+ -lcrypto \
+ src/base/lib_libopensaf_core_la-file_descriptor.lo \
+ src/base/lib_libopensaf_core_la-file_notify.lo \
src/base/lib_libopensaf_core_la-getenv.lo \
+ src/base/lib_libopensaf_core_la-hash.lo \
src/base/lib_libopensaf_core_la-log_message.lo \
src/base/lib_libopensaf_core_la-process.lo \
- src/base/lib_libopensaf_core_la-file_descriptor.lo \
- src/base/lib_libopensaf_core_la-file_notify.lo
+ src/base/lib_libopensaf_core_la-unix_server_socket.lo \
+ src/base/lib_libopensaf_core_la-unix_socket.lo
bin_libbase_test_SOURCES = \
- src/base/tests/unix_socket_test.cc \
src/base/tests/getenv_test.cc \
+ src/base/tests/hash_test.cc \
src/base/tests/log_message_test.cc \
src/base/tests/mock_logtrace.cc \
src/base/tests/mock_osaf_abort.cc \
@@ -198,8 +202,8 @@ bin_libbase_test_SOURCES = \
src/base/tests/time_add_test.cc \
src/base/tests/time_compare_test.cc \
src/base/tests/time_convert_test.cc \
- src/base/tests/file_notify_test.cc \
- src/base/tests/time_subtract_test.cc
+ src/base/tests/time_subtract_test.cc \
+ src/base/tests/unix_socket_test.cc
bin_libbase_test_LDADD = \
$(GTEST_DIR)/lib/libgtest.la \
diff --git a/src/base/hash.cc b/src/base/hash.cc
new file mode 100644
--- /dev/null
+++ b/src/base/hash.cc
@@ -0,0 +1,28 @@
+/* -*- OpenSAF -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ */
+
+#include "base/hash.h"
+
+namespace base {
+
+const char kHashFunctionAlphabet[64] = {
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O',
+ 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+ 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's',
+ 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
+ '8', '9', '-', '_'
+};
+
+} // namespace base
diff --git a/src/base/hash.h b/src/base/hash.h
new file mode 100644
--- /dev/null
+++ b/src/base/hash.h
@@ -0,0 +1,67 @@
+/* -*- OpenSAF -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ */
+
+#ifndef BASE_HASH_H_
+#define BASE_HASH_H_
+
+#include <openssl/sha.h>
+#include <cstdint>
+#include <string>
+
+namespace base {
+
+extern const char kHashFunctionAlphabet[64];
+
+// This function takes an arbitrary string as input parameter and returns
+// another string which is a hash of the input string generated using a
+// collision-resistant hash function. The probability that two different inputs
+// would generate the same output is small enough that it can be safely ignored
+// for all practical purposes.
+//
+// The return value of this function is a string of printable ASCII characters.
+// The length of the returned string will always be exactly 32 characters, and
+// the returned string is guaranteed to not contain any character that would be
+// illegal for use in a file name.
+//
+// Note: if you use this function you need to link your program with -lcrypto
+inline std::string Hash(const std::string& message) {
+ SHA512_CTX context;
+ SHA512_Init(&context);
+ context.h[0] = UINT64_C(0x010176140648b233);
+ context.h[1] = UINT64_C(0xdb92aeb1eebadd6f);
+ context.h[2] = UINT64_C(0x83a9e27aa1d5ea62);
+ context.h[3] = UINT64_C(0xec95f77eb609b4e1);
+ context.h[4] = UINT64_C(0x71a99185c75caefa);
+ context.h[5] = UINT64_C(0x006e8f08baf32e3c);
+ context.h[6] = UINT64_C(0x6a2b21abd2db2aec);
+ context.h[7] = UINT64_C(0x24926cdbd918a27f);
+ SHA512_Update(&context, message.data(), message.size());
+ unsigned char result[SHA512_DIGEST_LENGTH];
+ SHA512_Final(result, &context);
+ std::string encoded;
+ encoded.reserve(32);
+ for (int i = 0; i != 24; i += 3) {
+ uint64_t a = (result[i] << 16) | (result[i + 1] << 8) | result[i + 2];
+ encoded.push_back(kHashFunctionAlphabet[a >> 18]);
+ encoded.push_back(kHashFunctionAlphabet[(a >> 12) & 63]);
+ encoded.push_back(kHashFunctionAlphabet[(a >> 6) & 63]);
+ encoded.push_back(kHashFunctionAlphabet[a & 63]);
+ }
+ return encoded;
+}
+
+} // namespace base
+
+#endif // BASE_HASH_H_
diff --git a/src/base/tests/hash_test.cc b/src/base/tests/hash_test.cc
new file mode 100644
--- /dev/null
+++ b/src/base/tests/hash_test.cc
@@ -0,0 +1,109 @@
+/* -*- OpenSAF -*-
+ *
+ * Copyright Ericsson AB 2017 - All Rights Reserved.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. This file and program are licensed
+ * under the GNU Lesser General Public License Version 2.1, February 1999.
+ * The complete license can be accessed from the following location:
+ * http://opensource.org/licenses/lgpl-license.php
+ * See the Copying file included with the OpenSAF distribution for full
+ * licensing terms.
+ *
+ */
+
+#include <endian.h>
+#include <cstddef>
+#include <random>
+#include <string>
+#include "base/hash.h"
+#include "gtest/gtest.h"
+
+struct TestVector {
+ const char* key_data;
+ size_t key_size;
+ const char* hash_value;
+};
+
+#define TEST_VECTOR(key, hash) { key, sizeof(key) - 1, hash }
+
+static const TestVector test_vectors[] = {
+ TEST_VECTOR("", "mJbyfHPNxOzI7KPhb27rY6_gS2wNOSds"),
+ TEST_VECTOR("\000", "U-4lHisMY1zsvi2ry5wqlYKUMhhb_MX8"),
+ TEST_VECTOR("\001", "7R0FXuGlh60oucbCoEIyp97oPDI34hNn"),
+ TEST_VECTOR("\376", "X-7TtfTMWhw7T9CK1-yk8bRAlF_544MB"),
+ TEST_VECTOR("\377", "OMGVy2Bhf3bPvd_yYKNVn8AK-EhkSJN4"),
+ TEST_VECTOR(" ", "LOR-HJ8c_bFoH7LVc45B67zrxvqNp2ih"),
+ TEST_VECTOR("\t", "jwSZSrsTHsB4kB2nUvpebPSpvDdt8d7V"),
+ TEST_VECTOR("\n", "WlgTrOkNrltdky0QZv1B3jMG0D73h3YC"),
+ TEST_VECTOR("\r\n", "pAv_qrHWSbOLxiJmXB2ETosp_FiE-G4H"),
+ TEST_VECTOR("\\/:", "wyC3ktDwB4tvyzXBO5zx_iH76GKFmjxB"),
+ TEST_VECTOR("$abc", "xSHQCvFJpVfx4ofdholD-mzgxyJJHjYg"),
+ TEST_VECTOR("\000\000\000\000\000", "mzklNJ6l6vWVe73PvthH61RRsl90ygC_"),
+ TEST_VECTOR("123456", "E_7JXvueRDhde3Wq3W5jYSsts_LOWJNZ"),
+ TEST_VECTOR("1234567", "0cAgD2NO2ASyz39axMrnBdV_VuHn2PhC"),
+ TEST_VECTOR("12345678", "Uzmag7xvTQg40VBwOumXaugZxFZyRpB8"),
+ TEST_VECTOR("123456789", "3YfQdE3kVpdmBEaBHM4uCj1feXvixjYA"),
+
TEST_VECTOR("\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
+
"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
+
"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
+
"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
+
"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
+
"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
+ "\340\341\342\343\344\345\346\347\350\351\352\353\354\355",
+ "z2V3p2mUUigcBkYWSEw0yhz2f1v4M8Nb"),
+
TEST_VECTOR("\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
+
"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
+
"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
+
"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
+
"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
+
"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
+ "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356",
+ "WprfN6xOSNY9RHaNCkR12yEEx5hGfwHj"),
+
TEST_VECTOR("\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
+
"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
+
"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
+
"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
+
"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
+
"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
+ "\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356"
+ "\357",
+ "K3wQd-ZX5k7_AZ7p1qOwrehV5vkaJq9E"),
+
TEST_VECTOR("\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217"
+
"\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237"
+
"\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257"
+
"\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277"
+
"\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317"
+
"\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337"
+
"\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357"
+ "\360",
+ "O-ERJdo-W-iCV4b2QogLJmtR1gMIhlkx")
+};
+
+TEST(BaseHash, TestVectors) {
+ for (size_t i = 0; i < sizeof(test_vectors) / sizeof(test_vectors[0]); ++i) {
+ std::string key = std::string(test_vectors[i].key_data,
+ test_vectors[i].key_size);
+ std::string hash = std::string(test_vectors[i].hash_value);
+ std::string computed_hash = base::Hash(key);
+ EXPECT_EQ(hash, computed_hash);
+ }
+}
+
+TEST(BaseHash, LongRandomString) {
+ std::string key;
+ key.reserve(8000);
+ std::mt19937_64 generator(4711);
+ for (size_t i = 0; i != 1000; ++i) {
+ union {
+ char bytes[sizeof(uint64_t)];
+ uint64_t word;
+ };
+ word = htobe64(generator());
+ key.append(bytes, sizeof(uint64_t));
+ }
+ std::string hash = std::string("C_r2XVQjnVbnpQTMHO2OQJ2sn0YZi1py");
+ std::string computed_hash = base::Hash(key);
+ EXPECT_EQ(hash, computed_hash);
+}
------------------------------------------------------------------------------
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel