#include #include #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 [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); }