diff options
Diffstat (limited to 'utils/midpoint.c')
-rw-r--r-- | utils/midpoint.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/utils/midpoint.c b/utils/midpoint.c new file mode 100644 index 0000000..1a2e6f3 --- /dev/null +++ b/utils/midpoint.c @@ -0,0 +1,71 @@ +#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); +} |