summaryrefslogtreecommitdiffstats
path: root/utils
diff options
context:
space:
mode:
authorAnton Luka Šijanec <anton@sijanec.eu>2023-01-01 22:28:35 +0100
committerAnton Luka Šijanec <anton@sijanec.eu>2023-01-01 22:28:35 +0100
commitad9c2c45fa85f877fa0880269369e6dc9492a87d (patch)
treee20d53a11f060cad20c8423f53921054358c59e4 /utils
parentfixed bdecoding strncpy->memcpy +etc (diff)
downloadtravnik-ad9c2c45fa85f877fa0880269369e6dc9492a87d.tar
travnik-ad9c2c45fa85f877fa0880269369e6dc9492a87d.tar.gz
travnik-ad9c2c45fa85f877fa0880269369e6dc9492a87d.tar.bz2
travnik-ad9c2c45fa85f877fa0880269369e6dc9492a87d.tar.lz
travnik-ad9c2c45fa85f877fa0880269369e6dc9492a87d.tar.xz
travnik-ad9c2c45fa85f877fa0880269369e6dc9492a87d.tar.zst
travnik-ad9c2c45fa85f877fa0880269369e6dc9492a87d.zip
Diffstat (limited to 'utils')
-rw-r--r--utils/midpoint.c71
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);
+}