00001
00002
00003
00004
00005
00006
00007
00008 #include <b64/cdecode.h>
00009
00010 int base64_decode_value(char value_in)
00011 {
00012 static const char decoding[] = {62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-2,-1,-1,-1,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,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51};
00013 static const char decoding_size = sizeof(decoding);
00014 value_in -= 43;
00015 if (value_in < 0 || value_in > decoding_size) return -1;
00016 return decoding[(int)value_in];
00017 }
00018
00019 void base64_init_decodestate(base64_decodestate* state_in)
00020 {
00021 state_in->step = step_a;
00022 state_in->plainchar = 0;
00023 }
00024
00025 int base64_decode_block(const char* code_in, const int length_in, char* plaintext_out, base64_decodestate* state_in)
00026 {
00027 const char* codechar = code_in;
00028 char* plainchar = plaintext_out;
00029 char fragment;
00030
00031 *plainchar = state_in->plainchar;
00032
00033 switch (state_in->step)
00034 {
00035 while (1)
00036 {
00037 case step_a:
00038 do {
00039 if (codechar == code_in+length_in)
00040 {
00041 state_in->step = step_a;
00042 state_in->plainchar = *plainchar;
00043 return plainchar - plaintext_out;
00044 }
00045 fragment = (char)base64_decode_value(*codechar++);
00046 } while (fragment < 0);
00047 *plainchar = (fragment & 0x03f) << 2;
00048 case step_b:
00049 do {
00050 if (codechar == code_in+length_in)
00051 {
00052 state_in->step = step_b;
00053 state_in->plainchar = *plainchar;
00054 return plainchar - plaintext_out;
00055 }
00056 fragment = (char)base64_decode_value(*codechar++);
00057 } while (fragment < 0);
00058 *plainchar++ |= (fragment & 0x030) >> 4;
00059 *plainchar = (fragment & 0x00f) << 4;
00060 case step_c:
00061 do {
00062 if (codechar == code_in+length_in)
00063 {
00064 state_in->step = step_c;
00065 state_in->plainchar = *plainchar;
00066 return plainchar - plaintext_out;
00067 }
00068 fragment = (char)base64_decode_value(*codechar++);
00069 } while (fragment < 0);
00070 *plainchar++ |= (fragment & 0x03c) >> 2;
00071 *plainchar = (fragment & 0x003) << 6;
00072 case step_d:
00073 do {
00074 if (codechar == code_in+length_in)
00075 {
00076 state_in->step = step_d;
00077 state_in->plainchar = *plainchar;
00078 return plainchar - plaintext_out;
00079 }
00080 fragment = (char)base64_decode_value(*codechar++);
00081 } while (fragment < 0);
00082 *plainchar++ |= (fragment & 0x03f);
00083 }
00084 }
00085
00086 return plainchar - plaintext_out;
00087 }
00088