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 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 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 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 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 67 string RawDataToHexString(const string& str) { 68 return RawDataToHexString(reinterpret_cast<const u8*>(str.data()), 69 str.size()); 70 } 71 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