Home | History | Annotate | Download | only in quipper
      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