]> git.za3k.com Git - cryptopals.git/commitdiff
Initial commit
authorZachary Vance <za3k@za3k.com>
Sun, 14 May 2017 02:09:49 +0000 (19:09 -0700)
committerZachary Vance <za3k@za3k.com>
Sun, 14 May 2017 02:09:49 +0000 (19:09 -0700)
.gitignore [new file with mode: 0644]
Makefile [new file with mode: 0644]
io.c [new file with mode: 0644]
io.h [new file with mode: 0644]
io.test.c [new file with mode: 0644]

diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..a8be9d5
--- /dev/null
@@ -0,0 +1,2 @@
+*.o
+*.test
diff --git a/Makefile b/Makefile
new file mode 100644 (file)
index 0000000..637f5c5
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,14 @@
+CC=gcc
+ODIR=obj
+CFLAGS=
+
+all: io.o io.test.o
+%.test: %.o %.test.c
+       $(CC) -o $@ $? $(CFLAGS)
+test: io.test
+       ./io.test
+clean:
+       rm -f *.o a.out *.test
+
+%.o: %.c
+       $(CC) -c -o $@ $< $(CFLAGS)
diff --git a/io.c b/io.c
new file mode 100644 (file)
index 0000000..4650ff0
--- /dev/null
+++ b/io.c
@@ -0,0 +1,120 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+int decode_hex(char* src, char* dest, int *destlen) {
+    // Returns 1 for success, 0 for failure
+    const char valid_chars[] ="0123456789aAbBcCdDeEfF";
+    const char values[]      = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15};
+    const char ILLEGAL_CHAR = 255;
+    int i;
+    char conversion[256] = { ILLEGAL_CHAR }; 
+    for (i=0; i<sizeof(valid_chars); i++) {
+      conversion[valid_chars[i]] = values[i];
+    }
+    
+    char* srcp = src;
+    // Check for non-hex characters
+    while (*srcp != 0)
+      if (conversion[*srcp++] == ILLEGAL_CHAR) return 0;
+    srcp = src;
+    *destlen = 0;
+    if (strlen(src)%2) {
+      *dest++ = conversion[*srcp++];
+      *destlen++;
+    }
+    while (*(src+2) != 0) {
+      *dest = conversion[*srcp]*256 + conversion[*(srcp+1)];
+      srcp += 2;
+      *destlen++;
+    }
+    return 1;
+}
+
+int decode_base64(char* src, char* dest, int* destlen) {
+  char base64[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  const char ILLEGAL_CHAR = 255;
+  const char padding = '=';
+  int i;
+  char conversion[256] = {ILLEGAL_CHAR}; 
+  for (i=0; i<64; i++) {
+    conversion[base64[i]] = i;
+  }
+
+  if (strlen(src)%4) return 0; // We can't deal with strings unless they are padded
+
+  // Decode
+  *destlen=0;
+  while(*src != 0) {
+    if (*(src+1) == 0 ||
+        *(src+2) == 0 ||
+        *(src+3) == 0) return 0;
+    if (*src == padding || *(src+1) == padding) return 0;
+    if (*(src+2) == padding) {
+        // 2 padding characters
+        if(*(src+3) != padding) return 0;
+        if(*(src+4) != 0) return 0;
+        if (conversion[*src]     == ILLEGAL_CHAR ||
+            conversion[*(src+1)] == ILLEGAL_CHAR) return 0;
+        if (conversion[*(src+2)] & 0x0F != 0) return 0;
+
+        *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+        return 1;
+    } else if (*(src+3) == padding) {
+       // 1 padding character
+        if(*(src+4) != 0) return 0;
+        if (conversion[*src]     == ILLEGAL_CHAR ||
+            conversion[*(src+1)] == ILLEGAL_CHAR ||
+            conversion[*(src+2)] == ILLEGAL_CHAR) return 0;
+        if (conversion[*(src+2)] & 0x03 != 0) return 0;
+
+        *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+        *dest++ = (conversion[*(src+1)] & 0x0F) + (conversion[*(src+2)] & 0x3C >> 2);
+        return 1;
+    } else {
+        // 0 padding characters
+        *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+        *dest++ = (conversion[*(src+1)] & 0x0F) + (conversion[*(src+2)] & 0x3C >> 2);
+        *dest++ = (conversion[*(src+2)] & 0x03) + conversion[*(src+3)];
+        *destlen+=3;
+    }
+  }
+  *dest=0;
+  return 1;
+}
+
+void encode_base64(const char* src_bytes, int src_size, char* dest) {
+  const char conversion[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  const char padding = ' ';
+  const char* srcp = src_bytes;
+  while(src_size > 3) { // 3 bytes = 24 bits = 4 output
+    *dest++ = conversion[src_bytes[0] & 0xFC];
+    *dest++ = conversion[(src_bytes[0] << 6) + src_bytes[1] & 0xF0];
+    *dest++ = conversion[(src_bytes[1] << 4) + src_bytes[2] & 0xC0];
+    *dest++ = conversion[(src_bytes[2] << 2)];
+    src_bytes+=3;
+    src_size-=3;
+  }
+  if (src_size == 2) {
+    *dest++ = conversion[src_bytes[0] & 0xFC];
+    *dest++ = conversion[(src_bytes[0] << 6) + src_bytes[1] & 0xF0];
+    *dest++ = conversion[(src_bytes[1] << 4)];
+    *dest++ = padding;
+  } else if (src_size == 1) {
+    *dest++ = conversion[src_bytes[0] & 0xFC];
+    *dest++ = conversion[(src_bytes[0] << 6)];
+    *dest++ = padding;
+    *dest++ = padding;
+  }
+  *dest = 0;
+}
+
+void encode_hex(const char* src_bytes, int src_size, char* dest) {
+  char hex[17] = "0123456789ABCDEF";
+  int i;
+  for (i=0; i<src_size; i++) {
+    *dest++ = hex[src_bytes[src_size] & 0xF0];
+    *dest++ = hex[src_bytes[src_size] & 0x0F];
+  }
+  *dest = 0;
+}
diff --git a/io.h b/io.h
new file mode 100644 (file)
index 0000000..63d99c8
--- /dev/null
+++ b/io.h
@@ -0,0 +1,4 @@
+int decode_hex(char* src, char* dest, int *destlen);
+int decode_base64(char* src, char* dest, int* destlen);
+void encode_base64(const char* src_bytes, int src_size, char* dest);
+void encode_hex(const char* src_bytes, int src_size, char* dest);
diff --git a/io.test.c b/io.test.c
new file mode 100644 (file)
index 0000000..9d0128e
--- /dev/null
+++ b/io.test.c
@@ -0,0 +1,43 @@
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "io.h"
+
+int main() {
+   char sample_hex[] = "49276d206b696c6c696e6720796f757220627261696e206c696b65206120706f69736f6e6f7573206d757368726f6f6d";
+   char reencoded_hex[sizeof(sample_hex)*2];
+   char bytes[sizeof(sample_hex)], decoded_bytes[sizeof(sample_hex)];
+   int bytes_size, decoded_bytes_size;
+   if (!decode_hex(sample_hex, bytes, &bytes_size)) {
+     printf("Decode hex failed");
+     exit(1);
+   }
+   encode_hex(bytes, bytes_size, reencoded_hex);
+   if (strcmp(sample_hex, reencoded_hex) == 0) {
+     printf("hex decode/encode: success");
+   } else {
+     printf("Expected %s\n      Got: %s", sample_hex, reencoded_hex);
+   }
+
+   char expected_base64[] = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t";
+   char base64[sizeof(sample_hex)*4/3+5];
+   encode_base64(bytes, bytes_size, base64);
+   if (strcmp(base64,expected_base64)) {
+     printf("Base64 encode: success");
+   } else {
+     printf("Expected: %s\n     Got: %s", expected_base64, base64);
+     exit(1);
+   }
+
+   if (!decode_base64(base64, decoded_bytes, &decoded_bytes_size)) {
+     printf("Decode base64 failed");
+     exit(1);
+   }
+   if (bytes_size == decoded_bytes_size && memcmp(bytes, decoded_bytes, bytes_size) == 0) {
+     printf("Base64 decode: success");
+   } else {
+     printf("Base64 decode is wrong");
+     exit(1);
+   }
+
+}