| // Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chromiumos-wide-profiling/binary_data_utils.h" |
| |
| #include <openssl/md5.h> |
| #include <sys/stat.h> |
| |
| #include <cstddef> |
| #include <cstdlib> |
| #include <cstring> |
| #include <fstream> // NOLINT(readability/streams) |
| #include <iomanip> |
| |
| #include "base/logging.h" |
| #include "base/macros.h" |
| |
| namespace { |
| |
| // Number of hex digits in a byte. |
| const int kNumHexDigitsInByte = 2; |
| |
| } // namespace |
| |
| namespace quipper { |
| |
| static uint64_t Md5Prefix( |
| const unsigned char* data, |
| unsigned long length) { // NOLINT |
| uint64_t digest_prefix = 0; |
| unsigned char digest[MD5_DIGEST_LENGTH + 1]; |
| |
| MD5(data, length, digest); |
| // We need 64-bits / # of bits in a byte. |
| std::stringstream ss; |
| for (size_t i = 0; i < sizeof(uint64_t); i++) |
| // The setw(2) and setfill('0') calls are needed to make sure we output 2 |
| // hex characters for every 8-bits of the hash. |
| ss << std::hex << std::setw(2) << std::setfill('0') |
| << static_cast<unsigned int>(digest[i]); |
| ss >> digest_prefix; |
| return digest_prefix; |
| } |
| |
| uint64_t Md5Prefix(const string& input) { |
| auto data = reinterpret_cast<const unsigned char*>(input.data()); |
| return Md5Prefix(data, input.size()); |
| } |
| |
| uint64_t Md5Prefix(const std::vector<char>& input) { |
| auto data = reinterpret_cast<const unsigned char*>(input.data()); |
| return Md5Prefix(data, input.size()); |
| } |
| |
| string RawDataToHexString(const u8* array, size_t length) { |
| // Convert the bytes to hex digits one at a time. |
| // There will be kNumHexDigitsInByte hex digits, and 1 char for NUL. |
| char buffer[kNumHexDigitsInByte + 1]; |
| string result = ""; |
| for (size_t i = 0; i < length; ++i) { |
| snprintf(buffer, sizeof(buffer), "%02x", array[i]); |
| result += buffer; |
| } |
| return result; |
| } |
| |
| string RawDataToHexString(const string& str) { |
| return |
| RawDataToHexString(reinterpret_cast<const u8*>(str.data()), str.size()); |
| } |
| |
| bool HexStringToRawData(const string& str, u8* array, size_t length) { |
| const int kHexRadix = 16; |
| char* err; |
| // Loop through kNumHexDigitsInByte characters at a time (to get one byte) |
| // Stop when there are no more characters, or the array has been filled. |
| for (size_t i = 0; |
| (i + 1) * kNumHexDigitsInByte <= str.size() && i < length; |
| ++i) { |
| string one_byte = str.substr(i * kNumHexDigitsInByte, kNumHexDigitsInByte); |
| array[i] = strtol(one_byte.c_str(), &err, kHexRadix); |
| if (*err) |
| return false; |
| } |
| return true; |
| } |
| |
| } // namespace quipper |