libutil

C Utility Library
git clone http://git.omkov.net/libutil
Log | Tree | Refs | README | LICENCE | Download

AuthorJamozed <[email protected]>
Date2021-02-19 09:50:56
Commit0f438d6bdc3b02a9da12d766819f9d98932dfa44
Parent3f2ab85592d348aa136c54bc7e497a73ce06e614

base32: Implement base32 decoding

Diffstat

M src/base32.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-------
M src/base32.h | 2 +-

2 files changed, 55 insertions, 8 deletions

diff --git a/src/base32.c b/src/base32.c
index 5e0a619..3a47101 100644
--- a/src/base32.c
+++ b/src/base32.c
@@ -1,4 +1,4 @@
-// base32.c, version 0.1.0
+// base32.c, version 1.0.0
 // Base32 source file for OMKOV lib
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.
@@ -32,7 +32,6 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE SOFTWARE.
 
 #include "base32.h"
 
-#include <stdbool.h>
 #include <stdint.h>
 #include <stdlib.h>
 #include <string.h>
@@ -61,14 +60,14 @@ size_t b32encode(uint8_t *dst, uint8_t *src, size_t len) {
 		switch (len) {
 		case 1: {
 			*o++ = B32E[(i[0] & 0x07) << 2];
-			memset(o, '=', 6); o += 6;
+			memset(o, '=', 6);
 			break;
 		}
 		case 2: {
 			*o++ = B32E[((i[0] & 0x07) << 2) | (i[1] >> 6)];
 			*o++ = B32E[(i[1] >> 1) & 0x1F];
 			*o++ = B32E[(i[1] & 0x01) << 4];
-			memset(o, '=', 4); o += 4;
+			memset(o, '=', 4);
 			break;
 		}
 		case 3: {
@@ -76,7 +75,7 @@ size_t b32encode(uint8_t *dst, uint8_t *src, size_t len) {
 			*o++ = B32E[(i[1] >> 1) & 0x1F];
 			*o++ = B32E[((i[1] & 0x01) << 4) | (i[2] >> 4)];
 			*o++ = B32E[(i[2] & 0x0F) << 1];
-			memset(o, '=', 3); o += 3;
+			memset(o, '=', 3);
 			break;
 		}
 		case 4: {
@@ -97,9 +96,57 @@ size_t b32encode(uint8_t *dst, uint8_t *src, size_t len) {
 
 /* Decode Base32 */
 size_t b32decode(uint8_t *dst, uint8_t *src, size_t len) {
-	return 0;
+	register uint8_t *i = src, *o = dst;
+	
+	for (; src[len - 1] == '='; --len);
+	
+	for (; len >= 8; len -= 8) {
+		*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2);
+		*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4);
+		*o++ = (B32D[i[3]] << 4) | (B32D[i[4]] >> 1);
+		*o++ = (B32D[i[4]] << 7) | (B32D[i[5]] << 2) | (B32D[i[6]] >> 3);
+		*o++ = (B32D[i[6]] << 5) | (B32D[i[7]]); i += 8;
+	}
+	
+	switch (len) {
+	case 2: {
+		*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2);
+		*o++ = (B32D[i[1]] << 6);
+		break;
+	}
+	case 4: {
+		*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2);
+		*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4);
+		*o++ = (B32D[i[3]] << 4);
+		break;
+	}
+	case 5: {
+		*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2);
+		*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4);
+		*o++ = (B32D[i[3]] << 4) | (B32D[i[4]] >> 1);
+		*o++ = (B32D[i[4]] << 7);
+		break;
+	}
+	case 7: {
+		*o++ = (B32D[i[0]] << 3) | (B32D[i[1]] >> 2);
+		*o++ = (B32D[i[1]] << 6) | (B32D[i[2]] << 1) | (B32D[i[3]] >> 4);
+		*o++ = (B32D[i[3]] << 4) | (B32D[i[4]] >> 1);
+		*o++ = (B32D[i[4]] << 7) | (B32D[i[5]] << 2) | (B32D[i[6]] >> 3);
+		*o++ = (B32D[i[6]] << 5);
+		break;
+	}
+	}
+	
+	return o - dst;
 }
 
 static const uint8_t B32E[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
 
-static const uint8_t B32D[] = {};
+static const uint8_t B32D[] = {
+	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	 0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
+	 0,  0, 26, 27, 28, 29, 30, 31,  0,  0,  0,  0,  0,  0,  0,  0,
+	 0,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+	15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25
+};
diff --git a/src/base32.h b/src/base32.h
index 10e8fe6..5531b52 100644
--- a/src/base32.h
+++ b/src/base32.h
@@ -1,4 +1,4 @@
-// base32.h, version 0.1.0
+// base32.h, version 1.0.0
 // Base32 header file for OMKOV lib
 // Copyright (C) 2021, Jakob Wakeling
 // All rights reserved.