LoginSignup
1
5

More than 5 years have passed since last update.

VBAでWindowsAPIを使って、バイト配列を Base64変換

Posted at

Base64の変換アルゴリズムは割とシンプルでオウンコーディングできる程度のものですが、実はWindows APIが その機能を提供しています。
VBAで、これを使って、バイト配列をBase64に変換して文字列型変数に格納する方法を記します。

主となる関数
Private Declare PtrSafe Function CryptBinaryToString Lib "Crypt32.dll" Alias "CryptBinaryToStringW" ( _
    ByVal pbBinary As LongPtr, _
    ByVal cbBinary As Long, _
    ByVal dwFlags As Long, _
    ByVal pszString As LongPtr, _
    ByVal pcchString As LongPtr _
    ) As Long

Private Const CRYPT_STRING_BASE64 As Long = &H1&

'バイト配列をBASE64でエンコードしたUnicode文字列にする関数
'この関数にバイト配列を渡す際に、UTF-8変換したバイト配列を渡すのか
'SJIS変換したバイト配列を渡すのか、UTF16変換(無変換)したバイト配列を渡すのかで
'当然ながら出力される文字列が変わってきます。
Public Function CryptBytesToString(ByRef bData() As Byte) As String
    Dim pbBinary As LongPtr
    Dim cbBinary As Long
    If UBound(bData) = -1 Then
        Exit Function
    End If

    'バイト配列の先頭アドレス と 長さを取得
    pbBinary = VarPtr(bData(0))
    cbBinary = UBound(bData) - LBound(bData) + 1

    Dim nBufferSize As Long
    '変換後文字列の長さを取得し、変換後文字列を格納するだけのバッファを用意
    If CryptBinaryToString(pbBinary, cbBinary, CRYPT_STRING_BASE64, _
                                0, VarPtr(nBufferSize)) Then
        CryptBytesToString = String(nBufferSize, vbNullChar)
        '必要な長さ分用意した空文字列バッファの先頭アドレス(StrPtr)から変換結果で上書き
        If CryptBinaryToString(pbBinary, cbBinary, CRYPT_STRING_BASE64, _
                                StrPtr(CryptBytesToString), VarPtr(nBufferSize)) Then
        End If
    End If
End Function

以下がテストコードです。
wikipediaのBase64の項目に載っている"ABCDEFG"を変換してみます。
wikipediaの変換結果は、ASCII文字列あるいはSJISとしてみた場合の"ABCDEFG"の変換結果です。
VBの"ABCDEFG"はUNICODE文字列ですので、Aは 0x41 ではなく、 0x41 0x00 という2バイトなので、このままいくと、Base64変換結果は wikipediaに載っているものと異なります。
以下のテストコードでは、これを避けるために、いったんSJISに変換して得られたバイト配列をBase64に変換しています。

テストコード
'上のコードの下に続けて、以下のコードを書いてください。
'Unicode文字列をSJISとみなして、Base64に変換する関数
Public Function String_To_SJIS_To_Base64_String(ByVal sValue As String) As String
    If Len(sValue) = 0 Then
        Exit Function
    End If

    Dim bSjis() As Byte
    'Unicode文字列をSJISのバイト配列にいったん変換
    bSjis = StrConv(sValue, vbFromUnicode)
    'SJISのバイト配列からBase64に変換
    String_To_SJIS_To_Base64_String = CryptBytesToString(bSjis)
End Function

'テストコード
Sub Main()
    Debug.Print String_To_SJIS_To_Base64_String("あ")
    Debug.Print String_To_SJIS_To_Base64_String("ABCDEFG")

End Sub

実行結果は以下の通りです。

gqA=

QUJDREVGRw==
1
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
5