]> git.za3k.com Git - cryptopals.git/commitdiff
Base64 encode/decode working
authorZachary Vance <za3k@za3k.com>
Sun, 14 May 2017 04:56:49 +0000 (21:56 -0700)
committerZachary Vance <za3k@za3k.com>
Sun, 14 May 2017 04:56:49 +0000 (21:56 -0700)
io.c
io.test.c

diff --git a/io.c b/io.c
index 4650ff029d7014b7847eff15d80418eb5c4ed793..71438e7989d4e34c5b675189869cc8eec8cad2c8 100644 (file)
--- a/io.c
+++ b/io.c
@@ -2,55 +2,98 @@
 #include <string.h>
 #include <stdlib.h>
 
+void encode_hex(const char* src_bytes, int src_size, char* dest) {
+  const char hex[17] = "0123456789abcdef";
+  int i;
+  for (i=0; i<src_size; i++) {
+    *dest++ = hex[(src_bytes[i] & 0xF0) >> 4];
+    *dest++ = hex[src_bytes[i] & 0x0F];
+  }
+  *dest = 0;
+}
+
 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 values[]      = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 255};
     const char ILLEGAL_CHAR = 255;
     int i;
-    char conversion[256] = { ILLEGAL_CHAR }; 
-    for (i=0; i<sizeof(valid_chars); i++) {
+    char conversion[256]; 
+    for (i=0; i<256; i++)
+      conversion[i] = ILLEGAL_CHAR;
+    for (i=0; i<sizeof(valid_chars)-1; 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;
+      if (conversion[*srcp++] == ILLEGAL_CHAR)
+        return 0;
     srcp = src;
     *destlen = 0;
     if (strlen(src)%2) {
       *dest++ = conversion[*srcp++];
-      *destlen++;
+      (*destlen)++;
     }
-    while (*(src+2) != 0) {
-      *dest = conversion[*srcp]*256 + conversion[*(srcp+1)];
+    while (*srcp != 0) {
+      *dest++ = (conversion[*srcp]<<4) | conversion[*(srcp+1)];
       srcp += 2;
-      *destlen++;
+      (*destlen)++;
     }
     return 1;
 }
 
+void encode_base64(const char* src_bytes, int src_size, char* dest) {
+  const char conversion[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+  const char padding = ' ';
+  char* srcp = src_bytes;
+  while(src_size >= 3) { // 3 bytes = 24 bits = 4 output
+    dest[0] = conversion[(srcp[0] & 0xFC) >> 2];
+    dest[1] = conversion[(srcp[0] & 0x03) << 4 | (srcp[1] & 0xF0) >> 4];
+    dest[2] = conversion[(srcp[1] & 0x0F) << 2 | (srcp[2] & 0xC0) >> 6];
+    dest[3] = conversion[ srcp[2] & 0x3F];
+    srcp+=3;
+    dest+=4;
+    src_size-=3;
+  }
+  if (src_size == 2) {
+    dest[0] = conversion[(srcp[0] & 0xFC) >> 2];
+    dest[1] = conversion[(srcp[0] & 0x03) << 4 | (srcp[1] & 0xF0) >> 4];
+    dest[2] = conversion[(srcp[1] & 0x0F) << 2];
+    dest[3] = padding;
+    dest+=4;
+  } else if (src_size == 1) {
+    dest[0] = conversion[(srcp[0] & 0xFC) >> 2];
+    dest[1] = conversion[(srcp[0] & 0x03) << 4];
+    dest[2] = padding;
+    dest[3] = padding;
+    dest+=4;
+  }
+  *dest = 0;
+}
+
 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++) {
+  char conversion[256];
+  for (i=0; i<256; i++)
+    conversion[i] = 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
+  if (strlen(src)%4) { printf("Strings must be padded to a multiple of 4 bytes\n"); 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;
+        *(src+3) == 0) { printf("Strings must be padded to a multiple of 4 bytes\n"); return 0; }
     if (*src == padding || *(src+1) == padding) return 0;
     if (*(src+2) == padding) {
+        printf("2 padding\n");
         // 2 padding characters
         if(*(src+3) != padding) return 0;
         if(*(src+4) != 0) return 0;
@@ -58,9 +101,11 @@ int decode_base64(char* src, char* dest, int* destlen) {
             conversion[*(src+1)] == ILLEGAL_CHAR) return 0;
         if (conversion[*(src+2)] & 0x0F != 0) return 0;
 
-        *dest++ = conversion[*src] + (conversion[*(src+1)] & 0x30 >> 4);
+        dest[0] = (conversion[*src]     & 0xFF) << 2 | (conversion[*(src+1)] & 0x30) >> 4;
+        *destlen+=1;
         return 1;
     } else if (*(src+3) == padding) {
+        printf("1 padding\n");
        // 1 padding character
         if(*(src+4) != 0) return 0;
         if (conversion[*src]     == ILLEGAL_CHAR ||
@@ -68,53 +113,19 @@ int decode_base64(char* src, char* dest, int* destlen) {
             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);
+        dest[0] = (conversion[*src]     & 0xFF) << 2 | (conversion[*(src+1)] & 0x30) >> 4;
+        dest[1] = (conversion[*(src+1)] & 0x0F) << 4 | (conversion[*(src+2)] & 0x3C) >> 2;
+        *destlen+=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)];
+        dest[0] = (conversion[*src]     & 0x3F) << 2 | (conversion[*(src+1)] & 0x30) >> 4;
+        dest[1] = (conversion[*(src+1)] & 0x0F) << 4 | (conversion[*(src+2)] & 0x3C) >> 2;
+        dest[2] = (conversion[*(src+2)] & 0x03) << 6 | (conversion[*(src+3)] & 0x3F);
+        src+=4;
+        dest+=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;
-}
index 9d0128e7846e0e19b5b87f7fbf90769d701ad335..e21112ade5b7716c0bdc67a97f910a11c22f4812 100644 (file)
--- a/io.test.c
+++ b/io.test.c
@@ -5,38 +5,55 @@
 
 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;
+   char expected_bytes[] = {0x49, 0x27, 0x6d, 0x20, 0x6b, 0x69, 0x6c, 0x6c, 0x69, 0x6e, 0x67, 0x20, 0x79, 0x6f, 0x75, 0x72, 0x20, 0x62, 0x72, 0x61, 0x69, 0x6e, 0x20, 0x6c, 0x69, 0x6b, 0x65, 0x20, 0x61, 0x20, 0x70, 0x6f, 0x69, 0x73, 0x6f, 0x6e, 0x6f, 0x75, 0x73, 0x20, 0x6d, 0x75, 0x73, 0x68, 0x72, 0x6f, 0x6f, 0x6d};
+   char expected_base64[] = "SSdtIGtpbGxpbmcgeW91ciBicmFpbiBsaWtlIGEgcG9pc29ub3VzIG11c2hyb29t";
+
+   char bytes[sizeof(sample_hex)];
+   int bytes_size;
    if (!decode_hex(sample_hex, bytes, &bytes_size)) {
-     printf("Decode hex failed");
+     printf("Decode hex failed\n");
      exit(1);
    }
+   if (bytes_size != sizeof(expected_bytes)) {
+     printf("Decode hex wrong size %d\n", bytes_size);
+     exit(1);
+   }
+   if (memcmp(bytes, expected_bytes, bytes_size) == 0) {
+     printf("Decode hex: success\n");
+   } else {
+     printf("Decode hex: failure\n");
+   }
+
+   char reencoded_hex[sizeof(sample_hex)];
    encode_hex(bytes, bytes_size, reencoded_hex);
    if (strcmp(sample_hex, reencoded_hex) == 0) {
-     printf("hex decode/encode: success");
+     printf("Encode hex: success\n");
    } else {
-     printf("Expected %s\n      Got: %s", sample_hex, reencoded_hex);
+     printf("Encode hex: failure\n");
+     printf("Expected %s\n      Got: %s\n", sample_hex, reencoded_hex);
+     exit(1);
    }
 
-   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");
+   if (strcmp(base64,expected_base64) == 0) {
+     printf("Base64 encode: success\n");
    } else {
-     printf("Expected: %s\n     Got: %s", expected_base64, base64);
+     printf("Base64 encode: failure\n");
+     printf("Expected: %s\n     Got: %s\n", expected_base64, base64);
      exit(1);
    }
 
+   char decoded_bytes[sizeof(sample_hex)];
+   int decoded_bytes_size;
    if (!decode_base64(base64, decoded_bytes, &decoded_bytes_size)) {
-     printf("Decode base64 failed");
+     printf("Decode base64 failed\n");
      exit(1);
    }
    if (bytes_size == decoded_bytes_size && memcmp(bytes, decoded_bytes, bytes_size) == 0) {
-     printf("Base64 decode: success");
+     printf("Base64 decode: success\n");
    } else {
-     printf("Base64 decode is wrong");
+     printf("Base64 decode is wrong\n");
      exit(1);
    }