Skip to content

Commit

Permalink
Implement r_base32 APIs for my future self ##api
Browse files Browse the repository at this point in the history
  • Loading branch information
trufae authored Jul 9, 2024
1 parent d4df760 commit c9b159c
Show file tree
Hide file tree
Showing 6 changed files with 149 additions and 1 deletion.
1 change: 1 addition & 0 deletions libr/include/r_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ int gettimeofday (struct timeval* p, void* tz);
#include "r_util/r_new_rbtree.h"
#include "r_util/r_intervaltree.h"
#include "r_util/r_big.h"
#include "r_util/r_base32.h"
#include "r_util/r_base36.h"
#include "r_util/r_base64.h"
#include "r_util/r_base91.h"
Expand Down
22 changes: 22 additions & 0 deletions libr/include/r_util/r_base32.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#ifndef R2_BASE32_H
#define R2_BASE32_H

#ifdef __cplusplus
extern "C" {
#endif

#if R2_USE_NEW_ABI

#include <r_util/r_base32.h>

R_API char *r_base32_encode(const ut8 *data, size_t input_length, size_t *output_length);
R_API ut8 *r_base32_decode(const char *data, size_t input_length, size_t *output_length);
R_API char *base32_encode_ut64(ut64 input);
R_API ut64 base32_decode_ut64(const char *input);
#endif

#ifdef __cplusplus
}
#endif

#endif
1 change: 1 addition & 0 deletions libr/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,7 @@ r_util_files = [
'include/r_util/r_asn1.h',
'include/r_util/r_assert.h',
'include/r_util/r_axml.h',
'include/r_util/r_base32.h',
'include/r_util/r_base36.h',
'include/r_util/r_base64.h',
'include/r_util/r_base91.h',
Expand Down
2 changes: 1 addition & 1 deletion libr/util/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ OBJS+=udiff.o bdiff.o stack.o queue.o tree.o idpool.o assert.o bplist.o
OBJS+=punycode.o pkcs7.o x509.o asn1.o asn1_str.o json_parser.o json_indent.o skiplist.o
OBJS+=pj.o rbtree.o intervaltree.o qrcode.o vector.o str_constpool.o str_trim.o
OBJS+=ascii_table.o protobuf.o graph_drawable.o axml.o sstext.o new_rbtree.o token.o
OBJS+=rvc.o rvc_git.o rvc_rvc.o bscanf.o rprintf.o
OBJS+=rvc.o rvc_git.o rvc_rvc.o bscanf.o rprintf.o base32.o

ifeq (${HAVE_GPERF},1)
OBJS+=d/ascii.o
Expand Down
123 changes: 123 additions & 0 deletions libr/util/base32.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/* radare - LGPL - Copyright 2024 - pancake */

#include <r_util/r_base32.h>

#if R2_USE_NEW_ABI
static const char base32_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
static const char base32_padding = '=';

// Utility function to find index in base32 alphabet
static int base32_char_index(char c) {
if (c >= 'A' && c <= 'Z') {
return c - 'A';
}
if (c >= '2' && c <= '7') {
return c - '2' + 26;
}
return -1;
}

R_API char *r_base32_encode(const ut8 *data, size_t input_length, size_t *output_length) {
size_t encoded_size = (input_length + 4) / 5 * 8;
char *encoded_data = (char *)malloc (encoded_size + 1);
if (!encoded_data) {
return NULL;
}

size_t i, j, index;
int current_byte, next_byte;
for (i = 0, j = 0; i < input_length;) {
current_byte = data[i++] << 8;
if (i < input_length) current_byte |= data[i++];
current_byte <<= 8;
if (i < input_length) current_byte |= data[i++];
current_byte <<= 8;
if (i < input_length) current_byte |= data[i++];
current_byte <<= 8;
if (i < input_length) current_byte |= data[i++];

for (index = 0; index < 8; index++) {
next_byte = (current_byte & 0xF8000000) >> 27;
encoded_data[j++] = base32_alphabet[next_byte];
current_byte <<= 5;
}
}

while (j < encoded_size) {
encoded_data[j++] = base32_padding;
}
encoded_data[encoded_size] = '\0';

if (output_length) {
*output_length = encoded_size;
}
return encoded_data;
}

R_API ut8 *r_base32_decode(const char *data, size_t input_length, size_t *output_length) {
if (input_length % 8 != 0) {
return NULL;
}

size_t decoded_size = input_length * 5 / 8;
unsigned char *decoded_data = (unsigned char *)malloc (decoded_size);
if (!decoded_data) {
return NULL;
}

size_t i, j, index;
int current_byte, next_byte;
for (i = 0, j = 0; i < input_length;) {
current_byte = 0;
for (index = 0; index < 8 && i < input_length; index++) {
next_byte = base32_char_index (toupper (data[i++]));
if (next_byte == -1) {
return NULL;
}
current_byte = (current_byte << 5) | next_byte;
}

for (index = 0; index < 5; index++) {
decoded_data[j++] = (current_byte & 0xFF000000) >> 24;
current_byte <<= 8;
}
}

if (output_length) {
*output_length = decoded_size;
}
return decoded_data;
}

R_API char *base32_encode_ut64(ut64 input) {
size_t encoded_size = 13; // Maximum 13 characters for 64-bit input
char *encoded_data = (char *)malloc (encoded_size + 1);
if (!encoded_data) {
return NULL;
}

int i;
for (i = 12; i >= 0; i--) {
encoded_data[i] = base32_alphabet[input & 0x1F];
input >>= 5;
}
encoded_data[encoded_size] = '\0';

return encoded_data;
}

// Decode function for ut64
R_API ut64 base32_decode_ut64(const char *input) {
ut64 decoded_value = 0;
int i;
for (i = 0; i < 13; i++) {
int index = base32_char_index (toupper (input[i]));
if (index == -1) {
return 0;
}
decoded_value = (decoded_value << 5) | index;
}
return decoded_value;
}

#endif
1 change: 1 addition & 0 deletions libr/util/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ r_util_sources = [
'sstext.c',
'getopt.c',
'print_code.c',
'base32.c',
'base36.c',
'base85.c',
'base91.c',
Expand Down

0 comments on commit c9b159c

Please sign in to comment.