|
1 #include <lua.h> |
|
2 #include <lauxlib.h> |
|
3 |
|
4 #include "b64.h" |
|
5 |
|
6 int frombase64(lua_State *L, const unsigned char *str, unsigned int len) { |
|
7 int d = 0, dlast = 0, phase = 0; |
|
8 unsigned char c; |
|
9 static int table[256] = { |
|
10 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 00-0F */ |
|
11 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 10-1F */ |
|
12 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, /* 20-2F */ |
|
13 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, /* 30-3F */ |
|
14 -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, /* 40-4F */ |
|
15 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, /* 50-5F */ |
|
16 -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, /* 60-6F */ |
|
17 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, /* 70-7F */ |
|
18 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 80-8F */ |
|
19 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* 90-9F */ |
|
20 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* A0-AF */ |
|
21 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* B0-BF */ |
|
22 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* C0-CF */ |
|
23 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* D0-DF */ |
|
24 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, /* E0-EF */ |
|
25 -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1 /* F0-FF */ |
|
26 }; |
|
27 luaL_Buffer b; |
|
28 |
|
29 luaL_buffinit(L, &b); |
|
30 for (; len--; ++str) { |
|
31 d = table[(int)*str]; |
|
32 if (d == -1) continue; |
|
33 switch(phase) { |
|
34 case 0: |
|
35 ++phase; |
|
36 break; |
|
37 case 1: |
|
38 c = ((dlast << 2) | ((d & 0x30) >> 4)); |
|
39 luaL_addchar(&b, c); |
|
40 ++phase; |
|
41 break; |
|
42 case 2: |
|
43 c = (((dlast & 0xf) << 4) | ((d & 0x3c) >> 2)); |
|
44 luaL_addchar(&b, c); |
|
45 ++phase; |
|
46 break; |
|
47 case 3: |
|
48 c = (((dlast & 0x03 ) << 6) | d); |
|
49 luaL_addchar(&b, c); |
|
50 phase = 0; |
|
51 break; |
|
52 } |
|
53 dlast = d; |
|
54 } |
|
55 luaL_pushresult(&b); |
|
56 return 1; |
|
57 } |
|
58 |
|
59 static void b64_encode(luaL_Buffer *b, unsigned int c1, unsigned int c2, unsigned int c3, int n) { |
|
60 static const char code[] = |
|
61 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
|
62 unsigned long tuple = c3 + 256UL * (c2 + 256UL * c1); |
|
63 int i; |
|
64 char s[4]; |
|
65 |
|
66 for (i = 0; i < 4; i++) { |
|
67 s[3-i] = code[tuple % 64]; |
|
68 tuple /= 64; |
|
69 } |
|
70 for (i = n+1; i < 4; i++) s[i] = '='; |
|
71 luaL_addlstring(b, s, 4); |
|
72 } |
|
73 |
|
74 int tobase64(lua_State *L, int pos) { |
|
75 size_t l; |
|
76 const unsigned char *s = (const unsigned char*)luaL_checklstring(L, pos, &l); |
|
77 luaL_Buffer b; |
|
78 int n; |
|
79 |
|
80 luaL_buffinit(L, &b); |
|
81 for (n = l / 3; n--; s += 3) |
|
82 b64_encode(&b, s[0], s[1], s[2], 3); |
|
83 |
|
84 switch (l % 3) { |
|
85 case 1: |
|
86 b64_encode(&b, s[0], 0, 0, 1); |
|
87 break; |
|
88 case 2: |
|
89 b64_encode(&b, s[0], s[1], 0, 2); |
|
90 break; |
|
91 } |
|
92 luaL_pushresult(&b); |
|
93 return 1; |
|
94 } |