2010年10月19日火曜日

Base64エンコード

---Base64.h---
// Base64.h : Base64.DLL のメイン ヘッダー ファイル
//

#pragma once


class __declspec(dllexport)CBase64
{
public:
 CBase64();
public:
 int gettableint(unsigned char str);
 unsigned short Encode(unsigned char* data, unsigned short datalen, unsigned char* buffer);
 unsigned short Decode(unsigned char* data, unsigned short datalen, unsigned char* buffer);
};


---Base64.cpp---
// Base64.cpp : DLL の初期化ルーチンです。
//


#include "Base64.h"

#if _DEBUG
#define _CRTDBG_MAP_ALLOC
#include 
#include 
#endif


// CBase64App コンストラクション

CBase64::CBase64()
{
   //初期処理
#if _DEBUG
 _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif

}


// CBase64App 初期化
// US-ASCII テーブル
static char base64_table[] = {
    'A','B','C','D','E','F','G','H',
    'I','J','K','L','M','N','O','P',
    'Q','R','S','T','U','V','W','X',
    'Y','Z','a','b','c','d','e','f',
    'g','h','i','j','k','l','m','n',
    'o','p','q','r','s','t','u','v',
    'w','x','y','z','0','1','2','3',
    '4','5','6','7','8','9','+','/'
//  '='
};


#define IsBit(c)    ((unsigned char)c) ? 0x01 : 0x00


int CBase64::gettableint(unsigned char str) {
    int i;
 for(i = 0; i < 64; i++) {
        if(str == base64_table[i]) break;
    }
    return i;
}

unsigned short CBase64::Encode(unsigned char* data, unsigned short datalen, unsigned char* buffer)
{
    unsigned short byte = 0;
    unsigned char bit = 0x80;
    unsigned char tmp;
    unsigned short size = 0, line = 0;
    int i;

    while(1) {
  if(byte >= datalen){
   break;
  }
        *buffer = '\0';
        for(i = 5; i >= 0; i--) {
            tmp = IsBit(data[byte] & bit);
            *buffer |= tmp ? (tmp << i) : *buffer;
            bit >>= 1;
            if(bit == 0x00) {
                byte++;
    if(byte >= datalen){
     break;
    }
                bit = 0x80;
            }
        }
        *buffer = base64_table[*buffer];
        buffer++;
        size++;
        line++;
        // 改行
  /*
        if(line >= 76) {
            buffer[0] = '\r';
            buffer[1] = '\n';
//          buffer[2] = '\0';
            buffer += 2;
            size += 2;
            line = 0;
        }
  */
  // 今回は改行しないようにする
    }

    tmp = (unsigned char)((size / 4 * 4 + 4) - size);
    while(tmp--) {
        *buffer = '=';
        buffer++;
        size++;
        // 改行
  /*
        if(line >= 76) {
            buffer[0] = '\r';
            buffer[1] = '\n';
            buffer += 2;
            size += 2;
            line = 0;
        }
  */
  // 今回は改行しないようにする
    }
    *buffer = '\0';
    return size;
}

unsigned short CBase64::Decode(unsigned char* data, unsigned short datalen, unsigned char* buffer)
{
    int bit = 7;
    unsigned char tmp;
    unsigned char i, t;
    unsigned short size = 0;
    unsigned short byte=0;

    *buffer = '\0';
    while(1) {
        if( (data[byte] == '=') || (data[byte] == '\0') || (byte > datalen) )
            break;
        if( (data[byte] == '\n') || (data[byte] == '\r') ) {
            byte++;
            continue;
        }
        tmp = gettableint(data[byte]);
        if(tmp > 63) return 0;
        for(i = 0x20; i != 0; i >>= 1) {
            t = IsBit(tmp & i);
            *buffer |= t ? t << bit : *buffer;
            bit--;
            if(bit < 0) {
                buffer++;
                *buffer = '\0';
                size++;
                bit = 7;
            }
        }
        byte++;
    }

    return size;
}

0 件のコメント: