Skip to content
Browse files

Add base64 unpadded encoding

  • Loading branch information...
1 parent a981684 commit a77aa79f1ec598e9d2d9024e107925baa77fcdbf Joe Nardone committed Mar 16, 2012
Showing with 71 additions and 25 deletions.
  1. +35 −2 src/zt_base.c
  2. +6 −2 src/zt_base.h
  3. +30 −21 tests/base_test.c
View
37 src/zt_base.c
@@ -33,6 +33,38 @@ static zt_base_definition_t _base64_rfc = {
zt_base_encode_with_padding
};
+static zt_base_definition_t _base64_rfc_nopad = {
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/",
+ /* valid: alphanum, '+', '/'; allows CR,LF,'=',SP,TAB
+ * -1 (invalid) -2 (ignored)
+ */
+ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -2, -2, -1, -1, -2, -1, -1, /* 0-15 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 16-31 */
+ -2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 32-47 */
+ 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -2, -1, -1, /* 48-63 */
+ -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 64-79 */
+ 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 80-95 */
+ -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 96-111 */
+ 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 112-127 */
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
+ },
+ 64,
+ 3,
+ 4,
+ 6,
+ '=',
+ 0
+};
+
static zt_base_definition_t _base64_uri = {
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"abcdefghijklmnopqrstuvwxyz"
@@ -65,6 +97,7 @@ static zt_base_definition_t _base64_uri = {
zt_base_definition_t * zt_base64_rfc = &_base64_rfc;
+zt_base_definition_t * zt_base64_rfc_nopad = &_base64_rfc_nopad;
zt_base_definition_t * zt_base64_uri = &_base64_uri;
static zt_base_definition_t _base32_rfc = {
@@ -175,7 +208,7 @@ _valid_dictionary_p(zt_base_definition_t * def) {
#define MAKE_MASK(x) ((1<<x)-1)
int
-zt_base_encode(zt_base_definition_t * def, void * in, size_t in_bytes, void **out, size_t *out_bytes) {
+zt_base_encode(zt_base_definition_t * def, const void * in, size_t in_bytes, void **out, size_t *out_bytes) {
size_t ocount;
size_t lcount;
size_t mod;
@@ -298,7 +331,7 @@ zt_base_encode(zt_base_definition_t * def, void * in, size_t in_bytes, void **ou
* calloc'd and must be free()'d by the user.
*/
int
-zt_base_decode(zt_base_definition_t * def, void * in, size_t in_bytes, void ** out, size_t * out_bytes) {
+zt_base_decode(zt_base_definition_t * def, const void * in, size_t in_bytes, void ** out, size_t * out_bytes) {
const unsigned char * inp;
unsigned char * outp;
int oval = 0;
View
8 src/zt_base.h
@@ -25,18 +25,22 @@ typedef struct zt_base_definition {
} zt_base_definition_t;
extern zt_base_definition_t * zt_base64_rfc; /* rfc 3548/4648 definition */
+extern zt_base_definition_t * zt_base64_rfc_nopad; /* rfc 3548/4648 definition, but no padding */
extern zt_base_definition_t * zt_base64_uri; /* rfc 3548/4648 URI safe definition */
extern zt_base_definition_t * zt_base32_rfc; /* rfc 3548/4648 definition */
extern zt_base_definition_t * zt_base32_hex; /* rfc 4648 HEX definition */
extern zt_base_definition_t * zt_base16_rfc; /* rfc 3548/4648 definition */
int
-zt_base_encode(zt_base_definition_t *def, void *in, size_t in_bytes, void **out, size_t *out_bytes);
+zt_base_encode(zt_base_definition_t *def, const void *in, size_t in_bytes, void **out, size_t *out_bytes);
#define zt_base64_encode(in, in_bytes, out, out_bytes) \
zt_base_encode(zt_base64_rfc, in, in_bytes, out, out_bytes)
+#define zt_base64_encode_nopad(in, in_bytes, out, out_bytes) \
+ zt_base_encode(zt_base64_rfc_nopad, in, in_bytes, out, out_bytes)
+
#define zt_base64_encode_uri(in, in_bytes, out, out_bytes) \
zt_base_encode(zt_base64_encode_uri, in, in_bytes, out, out_bytes)
@@ -49,7 +53,7 @@ zt_base_encode(zt_base_definition_t *def, void *in, size_t in_bytes, void **out,
#define zt_base16_encode(in, in_bytes, out, out_bytes) \
zt_base_encode(zt_base16_encode_rfc, in, in_bytes, out, out_bytes)
-int zt_base_decode(zt_base_definition_t * def, void * in, size_t in_bytes, void **out, size_t *out_bytes);
+int zt_base_decode(zt_base_definition_t * def, const void * in, size_t in_bytes, void **out, size_t *out_bytes);
#define zt_base64_decode(in, in_bytes, out, out_bytes) \
zt_base_decode(zt_base64_rfc, in, in_bytes, out, out_bytes)
View
51 tests/base_test.c
@@ -5,26 +5,28 @@
#include <ctype.h>
#include <zt_base.h>
-#define test_encoding(_base, _data, _len, _result1, _result2) \
- do { unsigned char * cdata = (unsigned char *)_data; \
- char * result = malloc(20); \
- int ret; \
- size_t len; \
- void **rptr = (void **)&result; \
- memset(result, 0, 20); \
- len = 20; \
- ZT_BIT_UNSET(_base->flags, zt_base_encode_with_padding); \
- ret = zt_base_encode(_base, cdata, _len, rptr, &len); \
- ZT_UNIT_ASSERT(test, !ret); \
- ZT_UNIT_ASSERT(test, strcmp(result, _result1) == 0); \
- ZT_UNIT_ASSERT(test, strlen(result) == len); \
- ZT_BIT_SET(_base->flags, zt_base_encode_with_padding); \
- \
- memset(result, 0, 20); \
- len = 20; \
- ret = zt_base_encode(_base, cdata, _len, rptr, &len); \
- ZT_UNIT_ASSERT(test, !ret); \
- ZT_UNIT_ASSERT(test, strcmp(result, _result2) == 0); \
+#define test_encoding(_base, _data, _len, _result1, _result2) \
+ do { unsigned char * cdata = (unsigned char *)_data; \
+ char * result = malloc(20); \
+ int ret; \
+ size_t len; \
+ bool bitisset = false; \
+ void **rptr = (void **)&result; \
+ memset(result, 0, 20); \
+ len = 20; \
+ bitisset = ZT_BIT_ISSET(_base->flags, zt_base_encode_with_padding); \
+ ZT_BIT_UNSET(_base->flags, zt_base_encode_with_padding); \
+ ret = zt_base_encode(_base, cdata, _len, rptr, &len); \
+ ZT_UNIT_ASSERT(test, !ret); \
+ ZT_UNIT_ASSERT(test, strcmp(result, _result1) == 0); \
+ ZT_UNIT_ASSERT(test, strlen(result) == len); \
+ if (bitisset) ZT_BIT_SET(_base->flags, zt_base_encode_with_padding); \
+ \
+ memset(result, 0, 20); \
+ len = 20; \
+ ret = zt_base_encode(_base, cdata, _len, rptr, &len); \
+ ZT_UNIT_ASSERT(test, !ret); \
+ ZT_UNIT_ASSERT(test, strcmp(result, _result2) == 0); \
ZT_UNIT_ASSERT(test, strlen(result) == len); zt_free(result);} while (0)
#define test_decoding(_base, _data, _len, _result1, _result2) \
@@ -141,6 +143,14 @@ encoding_tests(struct zt_unit_test * test, void * _data UNUSED) {
test_encoding(zt_base64_rfc, "fooba", 5, "Zm9vYmE", "Zm9vYmE=");
test_encoding(zt_base64_rfc, "foobar", 6, "Zm9vYmFy", "Zm9vYmFy");
+ /* RFC4648 nopad test vectors */
+ test_encoding(zt_base64_rfc_nopad, "", 0, "", "");
+ test_encoding(zt_base64_rfc_nopad, "f", 1, "Zg", "Zg");
+ test_encoding(zt_base64_rfc_nopad, "fo", 2, "Zm8", "Zm8");
+ test_encoding(zt_base64_rfc_nopad, "foo", 3, "Zm9v", "Zm9v");
+ test_encoding(zt_base64_rfc_nopad, "foob", 4, "Zm9vYg", "Zm9vYg");
+ test_encoding(zt_base64_rfc_nopad, "fooba", 5, "Zm9vYmE", "Zm9vYmE");
+ test_encoding(zt_base64_rfc_nopad, "foobar", 6, "Zm9vYmFy", "Zm9vYmFy");
/* base 32 tests */
@@ -230,7 +240,6 @@ decoding_tests(struct zt_unit_test * test, void * _data UNUSED) {
test_decoding(zt_base64_rfc, "fooba", 5, "Zm9vYmE", "Zm9vYmE=");
test_decoding(zt_base64_rfc, "foobar", 6, "Zm9vYmFy", "Zm9vYmFy");
-
/* base 32 tests */
test_decoding(zt_base32_rfc, "", 0, "", "");

0 comments on commit a77aa79

Please sign in to comment.
Something went wrong with that request. Please try again.