Krzysztof KWIATKOWSKI преди 9 години
ревизия
65e6de9f44
променени са 4 файла, в които са добавени 190 реда и са изтрити 0 реда
  1. +5
    -0
      Makefile
  2. +135
    -0
      utils/hex_to_base64.cpp
  3. +1
    -0
      utils/hex_to_base64.h
  4. +49
    -0
      utils/utils_tester.cpp

+ 5
- 0
Makefile Целия файл

@@ -0,0 +1,5 @@
all:
gcc -g -c utils/hex_to_base64.cpp -o obj/hex_to_base64.o
gcc -g -c utils/utils_tester.cpp -o obj/utils_tester.o
gcc -g -o utils_tester obj/hex_to_base64.o obj/utils_tester.o

+ 135
- 0
utils/hex_to_base64.cpp Целия файл

@@ -0,0 +1,135 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MIN(a,b) a<b ? a : b

unsigned short char_to_hex[256] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
// 50
0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e,
0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x0b, 0x0c,
0x0d, 0x0e, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

// 100: this rest shouldn't be needed
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};

unsigned char int_to_base64[65] = {
'A','B','C','D','E','F','G','H','I','J',
'K','L','M','N','O','P','Q','R','S','T',
'U','V','W','X','Y','Z','a','b','c','d',
'e','f','g','h','i','j','k','l','m','n',
'o','p','q','r','s','t','u','v','w','x',
'y','z','0','1','2','3','4','5','6','7',
'8','9','+','/','='
};

// data stores 24 bits
struct int24 {
unsigned int data:24;
};

void read_bytes(const char* hex_buff, int24& o_data, unsigned len=3)
{
unsigned char hex;
for(int i=0; i<len; ++i)
{
o_data.data <<= 8;

hex = char_to_hex[ hex_buff[0+(i*2)] ] * 16;
hex += char_to_hex[ hex_buff[1+(i*2)] ];
o_data.data |= hex;
}
}

/* -----------------------------------------------------------------------------
* @brief Converts HEX to Base64
*
* @param hex_buf : buffer with hexes to be converted
* base64_buff : output buffer. has to be \0 initialized
* hex_buff_len: length of hex_buff
*
* @returns number of characters written to base64_buf
*
* @remarks remarks
*
*------------------------------------------------------------------------------ */
unsigned hex_to_base64(const char* hex_buff, char*& base64_buff, unsigned hex_buff_len )
{
unsigned j=0;
const unsigned unaligned = hex_buff_len % 6;
unsigned len_aligned = hex_buff_len - unaligned;

int24 data;
unsigned char idx1,idx2,idx3,idx4;
for(unsigned i=0; i<len_aligned; i+=6)
{
data.data = 0;
read_bytes(hex_buff+i, data, 3);

idx1 = 0x3F & (data.data >> 6*3);
idx2 = 0x3F & (data.data >> 6*2);
idx3 = 0x3F & (data.data >> 6);
idx4 = 0x3F & data.data;

base64_buff[j++] = int_to_base64[idx1];
base64_buff[j++] = int_to_base64[idx2];
base64_buff[j++] = int_to_base64[idx3];
base64_buff[j++] = int_to_base64[idx4];
}

if(unaligned)
{
const unsigned rest_bytes = unaligned/2;
data.data = 0;
read_bytes(hex_buff+len_aligned, data, rest_bytes);

if(rest_bytes==1)
{
if( ( data.data & (data.data & 0x3F) ) == data.data)
{
base64_buff[j++] = int_to_base64[ data.data ];
}
else
{
idx1 =(data.data >> 2 ) & 0x3F;
idx2 = data.data & 0x3;
base64_buff[j++] = int_to_base64[ idx1 ];
base64_buff[j++] = int_to_base64[ idx2 ];
}
}
else if(rest_bytes==2)
{
idx1 =(data.data >> 10 ) & 0x3F;
idx2 =(data.data >> 4 ) & 0x3F;
idx3 =(data.data ) & 15;

base64_buff[j++] = int_to_base64[ idx1 ];
base64_buff[j++] = int_to_base64[ idx2 ];
base64_buff[j++] = int_to_base64[ idx3 ];
}
}
return j;
}

+ 1
- 0
utils/hex_to_base64.h Целия файл

@@ -0,0 +1 @@
unsigned hex_to_base64(const char* hex_buff, char*& base64_buff, unsigned hex_buff_len );

+ 49
- 0
utils/utils_tester.cpp Целия файл

@@ -0,0 +1,49 @@
#include "hex_to_base64.h"
#include <string.h>
#include <assert.h>
#include <stdio.h>

void hex_to_base64_text() {
const char test_buff1[] ="49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
const char expected_buff1[] ="SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t";

const char test_buff2[] ="4927";
const char expected_buff2[] ="SSH";

const char test_buff3[] ="49";
const char expected_buff3[] ="SB";

const char test_buff4[] ="33";
const char expected_buff4[] ="z";

char output[256];
char* po=output;

memset (output,'\0', 256);
hex_to_base64(test_buff1, po, strlen(test_buff1) );
// printf("%s\n", output);
assert( memcmp(expected_buff1, output, strlen(expected_buff1)) == 0 );
assert( strlen(expected_buff1) == strlen(output));
// test case when there are 2 hex'es
memset (output,'\0', 256);
hex_to_base64(test_buff2, po, strlen(test_buff2) );
assert( memcmp(expected_buff2, output, strlen(expected_buff2)) == 0 );
assert( strlen(expected_buff2) == strlen(output));

// test case when there is 1 hex
memset (output,'\0', 256);
hex_to_base64(test_buff3, po, strlen(test_buff3) );
assert( memcmp(expected_buff3, output, strlen(expected_buff3)) == 0 );
assert( strlen(expected_buff3) == strlen(output));

// test case when there is 1 char
memset (output,'\0', 256);
hex_to_base64(test_buff4, po, strlen(test_buff4) );
assert( memcmp(expected_buff4, output, strlen(expected_buff4)) == 0 );
assert( strlen(expected_buff4) == strlen(output));
}

int main() {
hex_to_base64_text();
}

Зареждане…
Отказ
Запис