1 | |
---|
2 | #include <stdio.h> |
---|
3 | #include <stdlib.h> |
---|
4 | #include <string.h> |
---|
5 | |
---|
6 | static int debug=0; |
---|
7 | char* abac_decode_string(char *); |
---|
8 | |
---|
9 | /* encode table */ |
---|
10 | static const char encode64url[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
---|
11 | |
---|
12 | /* decode table Tables */ |
---|
13 | /* |
---|
14 | static const char decode64url[]="=====rstuvwxyz========>?@ABCDEFGHIJKLMNOPQRSTUVW======XYZ[\\]^_=abcdefghijklmnopq"; |
---|
15 | */ |
---|
16 | /* 6 14 26 48 5557 65 81*/ |
---|
17 | |
---|
18 | static const char decode64url[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; |
---|
19 | |
---|
20 | /* in 3, out 4 */ |
---|
21 | static void _encode_block( char in[3], char out[4] , int len ) |
---|
22 | { |
---|
23 | out[0] = encode64url[ in[0] >> 2 ]; |
---|
24 | out[1] = encode64url[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; |
---|
25 | out[2] = (unsigned char) (len > 1 ? encode64url[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); |
---|
26 | out[3] = (unsigned char) (len > 2 ? encode64url[ in[2] & 0x3f ] : '='); |
---|
27 | if(0) { |
---|
28 | printf("len: %d\n", len); |
---|
29 | printf("IN: (%c) (%c) (%c)\n", in[0], in[1], in[2]); |
---|
30 | printf("OUT: (%c) (%c) (%c) (%c)\n", out[0], out[1], out[2], out[3]); |
---|
31 | } |
---|
32 | } |
---|
33 | |
---|
34 | /* in 4, out 3 */ |
---|
35 | void _decode_block( char in[4], char out[3] ) |
---|
36 | { |
---|
37 | out[0] = (unsigned char ) (in[0] << 2 | in[1] >> 4); |
---|
38 | out[1] = (unsigned char ) (in[1] << 4 | in[2] >> 2); |
---|
39 | out[2] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]); |
---|
40 | if(0) { |
---|
41 | printf("IN: (%c) (%c) (%c) (%c)\n", in[0], in[1], in[2], in[3]); |
---|
42 | printf("OUT: (%c) (%c) (%c)\n", out[0], out[1], out[2]); |
---|
43 | } |
---|
44 | } |
---|
45 | |
---|
46 | |
---|
47 | /* |
---|
48 | return a deep copy of encoded string |
---|
49 | */ |
---|
50 | char* abac_encode_string(char* string) |
---|
51 | { |
---|
52 | char *inbufptr, *outbufptr; |
---|
53 | int len=strlen(string); |
---|
54 | int olen, nlen; |
---|
55 | char *orig_string, *new_string; |
---|
56 | int hops; |
---|
57 | int i; |
---|
58 | |
---|
59 | if(len == 0) return strdup(""); |
---|
60 | |
---|
61 | if((len/3)*3 != len) { |
---|
62 | hops=(len/3)+1; |
---|
63 | olen=hops*3; |
---|
64 | orig_string=malloc(sizeof(char)*olen); |
---|
65 | strcpy(orig_string,string); |
---|
66 | for(i=len; i< olen; i++) |
---|
67 | orig_string[i]=0; |
---|
68 | } else { |
---|
69 | hops=len/3; |
---|
70 | olen=hops*3; |
---|
71 | orig_string=strdup(string); |
---|
72 | } |
---|
73 | nlen=(olen*4/3 +1); |
---|
74 | new_string = (char *) malloc(sizeof(char)*nlen); |
---|
75 | |
---|
76 | inbufptr=orig_string; |
---|
77 | outbufptr=new_string; |
---|
78 | if(debug) { |
---|
79 | printf("sizeof string %d\n", len); |
---|
80 | } |
---|
81 | |
---|
82 | int idx=0; |
---|
83 | for(i=1; i<=hops;i++) { |
---|
84 | int v=(len>(i*3))?3:(len-((i-1)*3)); |
---|
85 | _encode_block(inbufptr,outbufptr,v); |
---|
86 | inbufptr=inbufptr+3; |
---|
87 | outbufptr=outbufptr+4; |
---|
88 | idx=idx+3; |
---|
89 | } |
---|
90 | free(orig_string); |
---|
91 | new_string[nlen-1]='\0'; |
---|
92 | |
---|
93 | if(debug) { |
---|
94 | char *d=abac_decode_string(new_string); |
---|
95 | if(strcmp(d,string) !=0) { |
---|
96 | printf("ERROR, base64 encoding NOT OKAY\n"); |
---|
97 | printf("orig,(%s)\n", string); |
---|
98 | printf("new,(%s)\n", new_string); |
---|
99 | printf("decode,(%s)\n",d); |
---|
100 | } else printf(" base64 encoding OKAY\n"); |
---|
101 | /* free(d); */ |
---|
102 | } |
---|
103 | return new_string; |
---|
104 | } |
---|
105 | |
---|
106 | char* abac_decode_string(char *string) |
---|
107 | { |
---|
108 | char *inbufptr, *outbufptr; |
---|
109 | int len=strlen(string); |
---|
110 | int nlen; |
---|
111 | char *new_string; |
---|
112 | char *orig_string; |
---|
113 | int idx=0; |
---|
114 | int v=0; |
---|
115 | |
---|
116 | if(len==0) return strdup(""); |
---|
117 | int hops=len/4; // ignore any that is not in the size 4 blocks |
---|
118 | new_string=(char *)malloc(sizeof(char)*(hops*3+1)); |
---|
119 | new_string[hops*3]='\0'; |
---|
120 | orig_string=strdup(string); |
---|
121 | |
---|
122 | inbufptr=orig_string; |
---|
123 | outbufptr=new_string; |
---|
124 | char inbuf[4]; |
---|
125 | int i, j; |
---|
126 | |
---|
127 | for(i=1; i<=hops; i++) { |
---|
128 | for(j=0; j<4; j++) { |
---|
129 | char c=inbufptr[j]; |
---|
130 | if(c > 122 || c <43) { |
---|
131 | c=0; |
---|
132 | } else { |
---|
133 | if(0) printf("from %d, (%c)\n", c, c); |
---|
134 | c=decode64url[c-43]; |
---|
135 | if(0) printf("to %d, (%c)\n", c, c); |
---|
136 | } |
---|
137 | if(c) { |
---|
138 | if(c=='$') c=0; |
---|
139 | else c=c-61; |
---|
140 | } |
---|
141 | if(c) { |
---|
142 | inbufptr[j]=(c-1); |
---|
143 | } else { |
---|
144 | inbufptr[j]=0; |
---|
145 | } |
---|
146 | } |
---|
147 | _decode_block( inbufptr, outbufptr ); |
---|
148 | outbufptr=outbufptr+3; |
---|
149 | inbufptr=inbufptr+4; |
---|
150 | } |
---|
151 | free(orig_string); |
---|
152 | return new_string; |
---|
153 | } |
---|
154 | |
---|
155 | |
---|
156 | /***************** |
---|
157 | int main( int argc, char **argv ) |
---|
158 | { |
---|
159 | |
---|
160 | if(argc != 2) return 1; |
---|
161 | |
---|
162 | FILE *infile = fopen( argv[1], "r" ); |
---|
163 | |
---|
164 | int num=1000; |
---|
165 | char *string=(char *)malloc(sizeof(char)*num); |
---|
166 | |
---|
167 | int cnt=getline(&string,&num,infile); |
---|
168 | fclose(infile); |
---|
169 | if(cnt==0) return 0; |
---|
170 | if(string[cnt-1]=='\n') |
---|
171 | string[cnt-1]='\0'; |
---|
172 | |
---|
173 | char *i=abac_encode_string(string); |
---|
174 | printf("encoding into (%s)\n", i); |
---|
175 | char *o=abac_decode_string(i); |
---|
176 | printf("decode into (%s)\n", o); |
---|
177 | |
---|
178 | printf(" %d:%d:%d\n", strlen(string),strlen(i), strlen(o)); |
---|
179 | if(strcmp(string,o)==0) |
---|
180 | printf("OKAY \n"); |
---|
181 | else |
---|
182 | printf("NOT OKAY \n"); |
---|
183 | free(string); |
---|
184 | free(o); |
---|
185 | } |
---|
186 | ****************/ |
---|