#include <dht.c>
#include <error.h>
#define S0(x) (x ? x : "")
/**
* converts a hexadecimal string to bytes
*
* b and h may not overlap, unless they are the same address
*
* @param b [out] array of bytes to write to with capacity l
* @param h [in] array of hex to read from with 2l hex digits
* @param l [in] length of output array
*/
void hex2bin (unsigned char * b, const char * h, int l) {
for (int i = 0; i < l; i++) {
char ms = *h++;
char ls = *h++;
b[i] = (ms >= 'a' ? ms - 'a' + 10 : (ms >= 'A' ? ms - 'A' + 10 : ms - '0')) << 4;
b[i] |= (ls >= 'a' ? ls - 'a' + 10 : (ls >= 'A' ? ls - 'A' + 10 : ls - '0'));
}
}
int main (int argc, char ** argv) {
if (argc < 3)
error_at_line(1, 0, __FILE__, __LINE__, "%s <bin|add|subtract|divide|midpoint> <a> [b]", S0(argv[0]));
if (argv[1][0] == 'b' || argv[1][0] == 'B') {
unsigned char a[strlen(argv[2])/2+1];
a[strlen(argv[2])/2] = '\0';
hex2bin(a, argv[2], strlen(argv[2])/2);
if (strlen(argv[2]) != 40 || (argv[2] && strlen(argv[2]) != 40)) {
printf("%s\n", a);
return 0;
}
return 0;
}
if (strlen(argv[2]) != 40)
error_at_line(3, 0, __FILE__, __LINE__, "strlen(a) != 40 && !bin");
if (argv[1][0] == 'd' || argv[1][0] == 'D') {
unsigned char a[20];
hex2bin(a, argv[2], 20);
divide(a);
char out[41];
out[40] = '\0';
bin2hex(out, a, 20);
printf("%s\n", out);
return 0;
}
if (!argv[3])
error_at_line(2, 0, __FILE__, __LINE__, "!b && !bin && !divide");
if (strlen(argv[3]) != 40)
error_at_line(3, 0, __FILE__, __LINE__, "strlen(b) != 40 && !bin && !divide");
unsigned char a[20];
unsigned char b[20];
hex2bin(a, argv[2], 20);
hex2bin(b, argv[3], 20);
char out[41];
out[40] = '\0';
unsigned char r[20];
if (argv[1][0] == 'a' || argv[1][0] == 'A') {
memcpy(r, a, 20);
add(r, b);
} else if (argv[1][0] == 's' || argv[1][0] == 'S') {
memcpy(r, a, 20);
subtract(r, b);
} else {
midpoint(r, a, b);
}
bin2hex(out, r, 20);
printf("%s\n", out);
}