Last active
August 29, 2015 14:02
-
-
Save santa4nt/a2bb3c1474e9e9f56a9a to your computer and use it in GitHub Desktop.
Convert a raw byte string into a hex string.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <assert.h> | |
#include <limits.h> | |
static const char *hexchars = "0123456789abcdef"; | |
/** | |
* Convert a string of raw bytes into readable hex string. | |
* | |
* Input parameters: | |
* - bytes - a string of raw bytes | |
* - inlen - length of input, in bytes | |
* | |
* Output parameters: | |
* - buf - caller-supplied buffer space for output hex string | |
* - outlen - the valid length of said buffer space, in bytes | |
* | |
* Return value: 0 if success, the number of bytes needed in output buffer if not | |
*/ | |
int bytes2hexstr(const char *bytes, unsigned int inlen, | |
char *buf, unsigned int outlen) | |
{ | |
unsigned int i; | |
char byte; | |
if (!bytes || !inlen) | |
{ | |
return 0; | |
} | |
// `buf` needs to at least be of length (`inlen` * 2 + 1) since | |
// each byte translates to two characters in hex string, plus terminating zero | |
if (!buf || outlen < (inlen * 2 + 1)) | |
{ | |
return inlen * 2 + 1; | |
} | |
outlen = 0; | |
for (i = 0; i < inlen; i++) | |
{ | |
byte = bytes[i]; | |
buf[outlen++] = hexchars[((byte >> 4) & 0x0f)]; | |
buf[outlen++] = hexchars[(byte & 0x0f)]; | |
} | |
buf[outlen] = '\0'; | |
return 0; | |
} | |
#ifdef USE_BOOST_UT | |
#define BOOST_TEST_DYN_LINK | |
#define BOOST_TEST_MODULE bytes2hex_test | |
#include <boost/test/unit_test.hpp> | |
BOOST_AUTO_TEST_CASE(bytes2hex_empty_arguments) | |
{ | |
char outbuf[32]; | |
int res; | |
res = bytes2hexstr(NULL, 10, outbuf, 32); | |
BOOST_CHECK_EQUAL(res, 0); | |
res = bytes2hexstr("abc", 0, outbuf, 32); | |
BOOST_CHECK_EQUAL(res, 0); | |
res = bytes2hexstr("abc", 3, NULL, 32); | |
BOOST_CHECK_EQUAL(res, 7); | |
res = bytes2hexstr("abc", 3, outbuf, 0); | |
BOOST_CHECK_EQUAL(res, 7); | |
} | |
BOOST_AUTO_TEST_CASE(bytes2hex_string) | |
{ | |
const char *inbytes = "\x00\x01\xde\xad\xbe\xef"; | |
char outbuf[512]; | |
int res; | |
res = bytes2hexstr(inbytes, 6, outbuf, 0); | |
BOOST_CHECK_EQUAL(res, 13); | |
res = bytes2hexstr(inbytes, 6, outbuf, res); | |
BOOST_CHECK_EQUAL(res, 0); | |
BOOST_CHECK_EQUAL(outbuf, "0001deadbeef"); | |
} | |
BOOST_AUTO_TEST_CASE(bytes2hex_integer) | |
{ | |
char outbuf[512]; | |
int res; | |
unsigned int i = UINT_MAX; | |
const int uint_size_in_bytes = sizeof(unsigned int) / sizeof(char); | |
union _data | |
{ | |
unsigned int uint; | |
char bytes[uint_size_in_bytes]; | |
} data; | |
data.uint = i; | |
res = bytes2hexstr((const char *)data.bytes, uint_size_in_bytes, outbuf, 0); | |
BOOST_CHECK_EQUAL(res, 9); | |
res = bytes2hexstr((const char *)data.bytes, uint_size_in_bytes, outbuf, res); | |
BOOST_CHECK_EQUAL(res, 0); | |
BOOST_CHECK_EQUAL(outbuf, "ffffffff"); | |
} | |
#else | |
int main() | |
{ | |
char *inbytes; | |
char outbuf[512]; | |
int res; | |
{ | |
inbytes = (char *) "\x00\x01\xde\xad\xbe\xef"; | |
res = bytes2hexstr(inbytes, 6, outbuf, 0); | |
assert (res > 0); | |
res = bytes2hexstr(inbytes, 6, outbuf, res); | |
printf("%s\n", outbuf); | |
// output: "0001deadbeef" | |
} | |
{ | |
unsigned int i = UINT_MAX; | |
const int uint_size_in_bytes = sizeof(unsigned int) / sizeof(char); | |
union _data | |
{ | |
unsigned int uint; | |
char bytes[uint_size_in_bytes]; | |
} data; | |
data.uint = i; | |
res = bytes2hexstr(data.bytes, uint_size_in_bytes, outbuf, 0); | |
res = bytes2hexstr(data.bytes, uint_size_in_bytes, outbuf, res); | |
printf("%s\n", outbuf); | |
// output: "ffffffff" (unsigned int == DWORD == 32 bit, all 1s) | |
} | |
return 0; | |
} | |
#endif | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
CC = gcc | |
CFLAGS = -Wall -g -x c++ | |
LFLAGS = -lstdc++ -lboost_unit_test_framework | |
DEFINES = -DUSE_BOOST_UT | |
OBJDIR = obj | |
BINDIR = bin | |
TARGET = bytes2hex | |
all: $(TARGET) | |
$(TARGET): $(TARGET).cpp | |
mkdir -p $(OBJDIR) | |
$(CC) $(CFLAGS) $(DEFINES) -c $(TARGET).cpp -o $(OBJDIR)/$(TARGET).o | |
exe: $(TARGET) | |
mkdir -p $(BINDIR) | |
$(CC) $(OBJDIR)/$(TARGET).o $(LFLAGS) -o $(BINDIR)/$(TARGET) | |
run: exe | |
./$(BINDIR)/$(TARGET) | |
valg: exe | |
valgrind --leak-check=full -v ./$(BINDIR)/$(TARGET) | |
clean: | |
rm -rf $(BINDIR) $(OBJDIR) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment