1 // Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "binary_data_utils.h"
6
7 #include <openssl/md5.h>
8 #include <sys/stat.h>
9
10 #include <cstddef>
11 #include <cstdlib>
12 #include <cstring>
13 #include <fstream>
14 #include <iomanip>
15
16 #include "base/logging.h"
17 #include "base/macros.h"
18
19 namespace {
20
21 // Number of hex digits in a byte.
22 const int kNumHexDigitsInByte = 2;
23
24 } // namespace
25
26 namespace quipper {
27
Md5Prefix(const unsigned char * data,unsigned long length)28 static uint64_t Md5Prefix(const unsigned char* data,
29 unsigned long length) {
30 uint64_t digest_prefix = 0;
31 unsigned char digest[MD5_DIGEST_LENGTH + 1];
32
33 MD5(data, length, digest);
34 // We need 64-bits / # of bits in a byte.
35 std::stringstream ss;
36 for (size_t i = 0; i < sizeof(uint64_t); i++)
37 // The setw(2) and setfill('0') calls are needed to make sure we output 2
38 // hex characters for every 8-bits of the hash.
39 ss << std::hex << std::setw(2) << std::setfill('0')
40 << static_cast<unsigned int>(digest[i]);
41 ss >> digest_prefix;
42 return digest_prefix;
43 }
44
Md5Prefix(const string & input)45 uint64_t Md5Prefix(const string& input) {
46 auto data = reinterpret_cast<const unsigned char*>(input.data());
47 return Md5Prefix(data, input.size());
48 }
49
Md5Prefix(const std::vector<char> & input)50 uint64_t Md5Prefix(const std::vector<char>& input) {
51 auto data = reinterpret_cast<const unsigned char*>(input.data());
52 return Md5Prefix(data, input.size());
53 }
54
RawDataToHexString(const u8 * array,size_t length)55 string RawDataToHexString(const u8* array, size_t length) {
56 // Convert the bytes to hex digits one at a time.
57 // There will be kNumHexDigitsInByte hex digits, and 1 char for NUL.
58 char buffer[kNumHexDigitsInByte + 1];
59 string result = "";
60 for (size_t i = 0; i < length; ++i) {
61 snprintf(buffer, sizeof(buffer), "%02x", array[i]);
62 result += buffer;
63 }
64 return result;
65 }
66
RawDataToHexString(const string & str)67 string RawDataToHexString(const string& str) {
68 return RawDataToHexString(reinterpret_cast<const u8*>(str.data()),
69 str.size());
70 }
71
HexStringToRawData(const string & str,u8 * array,size_t length)72 bool HexStringToRawData(const string& str, u8* array, size_t length) {
73 const int kHexRadix = 16;
74 char* err;
75 // Loop through kNumHexDigitsInByte characters at a time (to get one byte)
76 // Stop when there are no more characters, or the array has been filled.
77 for (size_t i = 0; (i + 1) * kNumHexDigitsInByte <= str.size() && i < length;
78 ++i) {
79 string one_byte = str.substr(i * kNumHexDigitsInByte, kNumHexDigitsInByte);
80 array[i] = strtol(one_byte.c_str(), &err, kHexRadix);
81 if (*err) return false;
82 }
83 return true;
84 }
85
86 } // namespace quipper
87