ソフトウェア開発 Win32プログラミング

Base64エンコード

戻る


与えられたデータをBase64でエンコードするコードは以下の通り。

#include <windows.h>

CHAR base64table[] = 
    "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

#define B64_ENC(Ch) (CHAR) (base64table[(CHAR)(Ch) & 0x3f])

INT Base64EncodeSize(INT cbSrc)
{
    return ((cbSrc + 2) / 3) * 4 + 1;
}

INT Base64Encode(LPSTR pszDest, const BYTE *pbSrc, INT cbSrc)
{
    INT cchDest = 0;

    for ( ; cbSrc > 2; cbSrc -= 3, pbSrc += 3 )
    {
        *pszDest++ = B64_ENC(pbSrc[0] >> 2);
        *pszDest++ = B64_ENC(((pbSrc[0] << 4) & 0x30) | ((pbSrc[1] >> 4) & 0x0F));
        *pszDest++ = B64_ENC(((pbSrc[1] << 2) & 0x3C) | ((pbSrc[2] >> 6) & 0x03));
        *pszDest++ = B64_ENC(pbSrc[2] & 0x3F);
        cchDest += 4;
    }

    if (cbSrc == 1)
    {
        *pszDest++ = B64_ENC(pbSrc[0] >> 2);
        *pszDest++ = B64_ENC((pbSrc[0] << 4) & 0x30);
        *pszDest++ = '=';
        *pszDest++ = '=';
        cchDest += 4;
    }
    else if (cbSrc == 2)
    {
        *pszDest++ = B64_ENC(pbSrc[0] >> 2);
        *pszDest++ = B64_ENC(((pbSrc[0] << 4) & 0x30) | ((pbSrc[1] >> 4) & 0x0F));
        *pszDest++ = B64_ENC((pbSrc[1] << 2) & 0x3C);
        *pszDest++ = '=';
        cchDest += 4;
    }
    *pszDest = 0;

    return cchDest;
}

#ifdef UNITTEST
#include <cstdio>
#include <string>
#include <new>  // for bad_alloc
using namespace std;

#define LINE_MAX 72
#define BUFSIZE 0x10000

class DataStream
{
    LPSTR m_p;
    INT m_size;
public:
    DataStream()
    {
        m_p = (LPSTR)malloc(1);
        if (m_p == NULL) throw bad_alloc();
        m_size = 0;
        m_p[m_size] = '\0';
    }
    ~DataStream() { if (m_p != NULL) free(m_p); }
    LPSTR Ptr() { return m_p; }
    INT Size() const { return m_size; }
    VOID Append(LPCVOID p, INT size)
    {
        m_p = (LPSTR)realloc(m_p, m_size + size + 1);
        if (m_p == NULL) throw bad_alloc();
        CopyMemory(m_p + m_size, p, size);
        m_size += size;
        m_p[m_size] = '\0';
    }
};

int main(int argc, char **argv)
{
    CHAR buf[BUFSIZE];
    INT n;
    FILE *fin, *fout;
    DataStream ds;
    string s, s2;

    if (argc <= 1 || argc > 3)
    {
        fprintf(stderr,
            "base64en ver. 0.0 (base64 encoder)\n"
            "by Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>\n"
            "usage: base64en input_file > output_file\n");
        return 0;
    }

    fin = fopen(argv[1], "rb");
    if (fin == NULL)
    {
        fprintf(stderr, "base64en: cannot open input file: %s\n", argv[1]);
        return 2;
    }
    try
    {
        while((n = fread(buf, 1, BUFSIZE, fin)) != 0)
        {
            ds.Append(buf, n);
        }
    }
    catch(bad_alloc ba)
    {
        if (fin != stdin)
            fclose(fin);
        fprintf(stderr, "base64en: out of memory\n");
        return 1;
    }
    if (fin != stdin)
        fclose(fin);

    INT size = Base64EncodeSize(ds.Size());
    LPSTR psz = new CHAR[size];
    Base64Encode(psz, ds.Ptr(), ds.Size());
    s = psz;
    delete[] psz;

    if (3 == argc)
    {
        fout = fopen(argv[2], "w");
        if (fout == NULL)
        {
            fprintf(stderr, "base64en: cannot open output file: %s\n", argv[2]);
            return 3;
        }
    }
    else
        fout = stdout;

    while(s.size() > 0)
    {
        if (s.size() >= LINE_MAX)
        {
            s2 = s.substr(0, LINE_MAX);
            fprintf(fout, "%s\n", s2.c_str());
            fflush(fout);
            s = s.substr(LINE_MAX);
        }
        else
        {
            fprintf(fout, "%s\n", s.c_str());
            fflush(fout);
            s.clear();
        }
    }
    if (fout != stdout)
        fclose(fout);

    return 0;
}
#endif  // def UNITTEST

ソース: base64en.zip


戻る

©片山博文MZ
katayama.hirofumi.mz@gmail.com

inserted by FC2 system