はじめに
独自実装した理由はとくにないです.以下のような変種が自由に作れるから?
s32 encodeBase64(FILE* file, s32 length, const u8* src); s32 decodeBase64(u8* dst, FILE* file);
共通処理
Base64の文字テーブルと, インデックス検索関数./* This is free and unencumbered software released into the public domain. */ static const s8 Base64Chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const s8 Base64PadChar = '='; s32 getIndexBase64Chars(s8 c) { if('A'<=c && c<='Z'){ return c-'A'; }else if('a'<=c && c<='z'){ return c-'a' + 26; }else if('0'<=c && c<='9'){ return c-'0' + 52; } for(s32 i=62; i<64; ++i){ if(Base64Chars[i]==c){ return i; } } return 0; } bool isBase64(s32 c) { return std::isalnum(c) || '+'==c || '/'==c; } s32 getLengthEncodedBase64(s32 l) { l = l<<3; s32 n0 = l/6; if(0<(l-n0*6)){ ++n0; } s32 n1 = ((n0 + 3)>>2)<<2; return n1; } s32 getLengthDecodedBase64(s32 l) { return (l*6 + 7)>>3; }
Encode
s32 encodeBase64(s8* dst, s32 length, const u8* src) { ASSERT(NULL != dst); ASSERT(0<=length); ASSERT(NULL != src); u8 tmp[3]; s32 d=0; s32 l=0; for(s32 i=0; i<length; ++i){ tmp[l] = src[i]; ++l; if(3<=l){ dst[d+0] = Base64Chars[tmp[0]>>2]; dst[d+1] = Base64Chars[((tmp[0]&0x03U)<<4) | (tmp[1]>>4)]; dst[d+2] = Base64Chars[((tmp[1]&0x0FU)<<2) | (tmp[2]>>6)]; dst[d+3] = Base64Chars[(tmp[2]&0x3FU)]; d += 4; l = 0; } } if(0<l){ for(s32 j=l; j<3; ++j){ tmp[j] = 0; } dst[d+0] = Base64Chars[tmp[0]>>2]; dst[d+1] = Base64Chars[((tmp[0]&0x03U)<<4) | (tmp[1]>>4)]; dst[d+2] = Base64Chars[((tmp[1]&0x0FU)<<2) | (tmp[2]>>6)]; dst[d+3] = Base64Chars[(tmp[2]&0x3FU)]; s32 n = l<<3; s32 r = (l<<3)/6; if(0<(n-r*6)){ ++l; } for(s32 j=l; j<4; ++j){ dst[d+j] = Base64PadChar; } d+=4; } return d; }
Decode
s32 decodeBase64(u8* dst, s32 length, const s8* src) { ASSERT(NULL != dst); ASSERT(0<=length); ASSERT(NULL != src); s32 l=0; s32 d=0; u8 tmp[4]; for(s32 i=0; i<length && isBase64(src[i]) && Base64PadChar != src[i]; ++i) { tmp[l] = static_cast<u8>(getIndexBase64Chars(src[i])); ++l; if(4<=l){ dst[d+0] = (tmp[0]<<2) | ((tmp[1]&0x30U)>>4); dst[d+1] = (tmp[1]<<4) | ((tmp[2]&0x3CU)>>2); dst[d+2] = (tmp[2]<<6) | tmp[3]; d += 3; l=0; } } if(0<l){ for(s32 i=l; i<4; ++i){ tmp[i] = 0; } dst[d+0] = (tmp[0]<<2) | ((tmp[1]&0x30U)>>4); dst[d+1] = (tmp[1]<<4) | ((tmp[2]&0x3CU)>>2); dst[d+2] = (tmp[2]<<6) | tmp[3]; d += (l*6)>>3; } return d; }
0 件のコメント:
コメントを投稿