Created
March 6, 2017 11:06
-
-
Save buserror/06b85d7cea8809575636786f52c9e95d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* make tea CFLAGS="-std=gnu99" | |
* | |
* ./tea "hello there how r You" -d "FOF5;?9#LDQ2'MAI\LT286+]\$63@Q;JG" | |
* | |
* XXTEA Encoder/decoder test program | |
* (C) Michel Pollet <[email protected]> | |
*/ | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
#include <string.h> | |
#include <stdbool.h> | |
#define DEBUG | |
//#define TEST | |
#ifdef DEBUG | |
#define D(_w) _w | |
#else | |
#define D(_w) | |
#endif | |
#ifdef TEST | |
#define T(_w) _w | |
#else | |
#define T(_w) | |
#endif | |
/* Lifted from teh Wikipedia page */ | |
#define MX (z>>5^y<<2) + (y>>3^z<<4) ^ (sum^y) + (k[p&3^e]^z); | |
static void btea(uint32_t* v, uint8_t n, uint32_t* k) { | |
uint32_t z=v[n-1], y=v[0], sum=0, e, DELTA=0x9e3779b9; | |
long p, q ; | |
q = 6 + 52/n; | |
while (q-- > 0) { | |
sum += DELTA; | |
e = (sum >> 2) & 3; | |
for (p=0; p<n-1; p++) y = v[p+1], z = v[p] += MX; | |
y = v[0]; | |
z = v[n-1] += MX; | |
} | |
} | |
static void debtea(uint32_t* v, uint8_t n, uint32_t* k) { | |
uint32_t z=v[n-1], y=v[0], sum=0, e, DELTA=0x9e3779b9; | |
long p, q ; | |
q = 6 + 52/n; | |
sum = q*DELTA ; | |
while (sum != 0) { | |
e = (sum >> 2) & 3; | |
for (p=n-1; p>0; p--) z = v[p-1], y = v[p] -= MX; | |
z = v[n-1]; | |
y = v[0] -= MX; | |
sum -= DELTA; | |
} | |
} | |
/* | |
* This is a uuencode/decode -like format | |
*/ | |
static uint8_t uuencode(uint8_t * s, uint8_t l, uint8_t *d) { | |
if (l > 63) { | |
D(printf("%s: len > 63, truncating\n", __func__);) | |
l = 63; | |
} | |
// d[0] = ' ' + 1 + l; // encode the length as one char | |
uint8_t bl = (l + 2) / 3; | |
for (uint8_t bi = 0; bi < bl; bi++, s += 3, d += 4) { | |
d[0] = ' ' + (s[0] >> 2); | |
d[1] = ' ' + (((s[0] & 0x3) << 4) | (s[1] >> 4)); | |
d[2] = ' ' + (((s[1] & 0xf) << 2) | (s[2] >> 6)); | |
d[3] = ' ' + (s[2] & 0x3f); | |
// debug | |
T(d[4] = 0; printf("%02x:%02x:%02x %s\n", s[0], s[1], s[2], d);) | |
} | |
*d = 0; | |
return (bl * 4); // + 1; | |
} | |
static uint8_t uudecode(uint8_t * s, uint8_t l, uint8_t *d) { | |
if (l & 0x3) { | |
D(printf("%s: %d not a multiple of 4, padding\n", __func__, l);) | |
l = (l + 3) & ~3; | |
} | |
uint8_t bl = l / 4; | |
for (uint8_t bi = 0; bi < bl; bi++, s += 4, d += 3) { | |
d[0] = ((s[0] - ' ') << 2) | ((s[1] - ' ') >> 4); | |
d[1] = ((s[1] - ' ') << 4) | ((s[2] - ' ') >> 2); | |
d[2] = ((s[2] - ' ') << 6) | ((s[3] - ' ')); | |
T(printf("%02x:%02x:%02x %-4.4s\n", d[0],d[1],d[2], s);) | |
} | |
*d = 0; | |
return bl * 3; | |
} | |
int | |
main(int argc, const char *argv[]) | |
{ | |
char key[32] = "This is a test key"; | |
bool encode = true; | |
uint8_t padded[256]; | |
uint8_t buf_encode[256]; | |
uint8_t buf_uuencode[256]; | |
#ifdef TEST /* uuencode/decode self test */ | |
printf("uuencode test\n"); | |
uuencode(key, strlen(key), padded); | |
printf("uudecode test\n"); | |
uudecode(padded, strlen(padded), buf_uuencode); | |
//padded[strlen(key)] = 0; | |
printf("decoded: '%s' -- should be '%s'\n", buf_uuencode, key); | |
#endif | |
for (int i = 1; i < argc; i++) { | |
if (!strcmp(argv[i], "-d")) { | |
encode = false; | |
continue; | |
} else if (!strcmp(argv[i], "-e")) { | |
encode = true; | |
continue; | |
} else if (!strcmp(argv[i], "-k") && i < argc -1) { | |
memset(key, 0, sizeof(key)); | |
strncpy(key, argv[i], sizeof(key)-1); | |
} else if (argv[i][0] == '-') { | |
printf("%s invalid argument %s\n", argv[0], argv[i]); | |
exit(1); | |
} | |
memset(padded, 0, sizeof(padded)); | |
memset(buf_encode, 0, sizeof(buf_encode)); | |
memset(buf_uuencode, 0, sizeof(buf_uuencode)); | |
if (!encode) { | |
D(printf("decode: '%s' l:%d\n", argv[i], strlen(argv[i]));) | |
strncpy(buf_uuencode, argv[i], sizeof(buf_uuencode)-1); | |
} | |
if (encode) { | |
int l = strlen(argv[i]); | |
// todo, check size overflow | |
memcpy(padded, argv[i], l); | |
int b = (l + 3) / 4; | |
D(printf("encode %d to %d blocks\n", l, b);) | |
if (b < 2) { | |
printf("Not enough blocks (min 2) padding\n"); | |
b = 2; | |
} | |
btea((uint32_t*)padded, b, (uint32_t*)key); | |
int dl = uuencode(padded, b * 4, buf_uuencode); | |
printf("E:%03d '%s'\n", dl, buf_uuencode); | |
} | |
/* now re-decode it */ | |
int dl = uudecode(buf_uuencode, strlen(buf_uuencode), buf_encode); | |
D(printf("decode uu:%d to %d, %d blocks\n", strlen(buf_uuencode), | |
dl, dl / 4);) | |
if (dl < 2) dl = 2; | |
debtea((uint32_t*)buf_encode, dl / 4, (uint32_t*)key); | |
printf("D:%03d '%s'\n", dl, buf_encode); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment