Missing punctuation from C ++ hex2bin

When trying to duplicate PHP bin2hex($s)and pack('H*',$s)(aka hex2bin($s)in PHP 5.4.3+) in GCC / Linux C ++, I seem to understand this, except that it marks punctuation for some strange reason. Can you figure out what I can do wrong in the hex2bin () function? I compared PHP bin2hex () with mine and it seems to work there correctly, so the problem is in hex2bin ().

#include <strings.h>
#include <string>
#include <stdio.h>
#include <stdlib.h>
using namespace std;

string bin2hex(string s) {
  int nLen = s.length();
  string sOut;
  char cBuff[2];
  for (int i = 0; i < nLen; i++) {
    sprintf(cBuff,"%.2x",s[i]);
    sOut.append(cBuff);
    cBuff[0] = '\0';
  }
  return sOut;
}

string hex2bin(string s) {
  int nLen = s.length();
  string sOut;
  char cBuff1[2];
  char cBuff2[2];
  char cBuff[1];
  int n,n1,n2;
  for (int i = 0; i <= nLen; i+=2) {
    sprintf(cBuff1,"%c",s[i]);
    sprintf(cBuff2,"%c",s[i+1]);
    n1 = atoi(cBuff1);
    n2 = atoi(cBuff2);
    n = (n1 * 16) + n2;
    sprintf(cBuff,"%c",n);
    sOut.append(cBuff);
    cBuff[0] = '\0';
    cBuff1[0] = '\0';
    cBuff2[0] = '\0';
  }
  return sOut;
}

int main() {
  string s;
  string sResult;  
  s = "This is a 123 test.";
  sResult = bin2hex(s);
  printf("ENCODED: %s\n",sResult.c_str());
  sResult = hex2bin(sResult);
  printf("UNENCODED: %s\n",sResult.c_str());
  return 1;
}

This emits:

ENCODED: 5468697320697320612031323320746573742e
UNENCODED: This is a 123 test
+1
source share
4 answers

Ok, the sleeves are folded: look at the C ++ version:

Live on coliru

  • Do not use C strings unless you need to (sprintf to create a string is not ... very efficient)
  • iostreams / (std::hex)
  • hex2bin , " "
  • modicum hex2bin
#include <string>
#include <sstream>
#include <iomanip>

std::string bin2hex(std::string const &s) {
    std::ostringstream oss;

    for (auto ch : s)
        oss << std::hex << std::setw(2) << std::setfill('0') << (int) ch;

    return oss.str();
}

#include <cassert>
std::string hex2bin(std::string const& s) {
    assert(s.length() % 2 == 0);

    std::string sOut;
    sOut.reserve(s.length()/2);

    std::string extract;
    for (std::string::const_iterator pos = s.begin(); pos<s.end(); pos += 2)
    {
        extract.assign(pos, pos+2);
        sOut.push_back(std::stoi(extract, nullptr, 16));
    }
    return sOut;
}

#include <iostream>
int main() {
    std::cout << "ENCODED: " << bin2hex("This is a 123 test.")          << "\n";
    std::cout << "DECODED: " << hex2bin(bin2hex("This is a 123 test.")) << "\n";
}

:

ENCODED: 5468697320697320612031323320746573742e
DECODED: This is a 123 test.
+4

'.' : . , 2e, e atoi("e"), : , atoi() . strtol(str, 0, 16) , .

, sprintf(): . , snprintf(), . , ( i <= nLen nLen = s.length(), s[i] s[i+1]). , :

#include <string>
#include <sstream>
#include <iostream>
#include <iomanip>

std::string bin2hex(std::string s) {
    std::ostringstream out;
    out << std::hex << std::setfill('0');
    for (char c: s) {
        out << std::setw(2) << int(c);
    }
    return out.str();
}

std::string hex2bin(std::string s) {
    std::string rc;
    int nLen = s.length();
    int tmp;
    for (int i(0); i + 1 < nLen; i += 2) {
        if (std::istringstream(s.substr(i, 2)) >> std::hex >> tmp) {
            rc.push_back(tmp);
        }
    }
    return rc;
}

int main() {
  std::string s;
  std::string sResult;  
  s = "This is a 123 test.";
  sResult = bin2hex(s);
  std::cout << "ENCRYPTED: " << sResult << '\n';
  sResult = hex2bin(sResult);
  std::cout << "UNENCRYPTED: " << sResult << '\n';
  return 1;
}
+2

, atoi .

sprintf(cBuff1,"%c",s[i]);
sprintf(cBuff2,"%c",s[i+1]);
n1 = strtoul(cBuff1, 0, 16);
n2 = strtoul(cBuff2, 0, 16);

for

for (int i = 0; i < nLen; i+=2) {
+1
n1 = atoi(cBuff1);
n2 = atoi(cBuff2);
n = (n1 * 16) + n2;

if cbuff1, say, "a"then this will not work, as ait is not a digit. It works great for numbers that are "0-9" but not "af".

You will need to translate digits without digits to numeric values.

There are several ways to convert a string of hexadecimal value to byte. I think this is pretty decent:

int hexchar(char c)
{
   if (c >= '0' && c <= '9') return c - '0';
   // if you need to support upper-case hex:
   // c = tolower(c); 
   if (c >= 'a' && c <= 'f') return c - 'a' + 10; 
   // If we get here, panic
   cout << "Error, invalid hex digit:" << c << endl;
   return -1;
}

int hexbyte(string s)
{
    for(i = 0; i < s.length(); i+=2)
    {
       char c = hexbyte(s[i]);
       c <<= 4;
       c += hexbyte(s[i+1];
       cout << c;
    }
}
+1
source

Source: https://habr.com/ru/post/1629690/


All Articles