[三流君] −−> [VBAで楽しく] −−> [バックナンバー一覧]
−−> No.160 CODE BASE64の変換処理にチャレンジしてみた

CODE BASE64の変換処理にチャレンジしてみた

発行内容

CODE BASE64の変換処理にチャレンジしてみた

どうも、三流プログラマーのKen3です。

今回は、
BASE64の変換処理にチャレンジしてみます。

http://www.ken3.org/vba/lzh/vba160.lzh
にサンプルbase64test.xlsを圧縮しておきます、
Excel2000版ですが使ってみてください。

/* * 1.今回のキッカケ */

前回の No.159 IE 認証ページへのアクセス、basci認証ページって? http://www.ken3.org/vba/backno/vba159.html で、 設定したユーザーとパスワードの組み合わせ mailmaga:guest をBASE64変換して bWFpbG1hZ2E6Z3Vlc3Q= ヘッダーに指定 "Authorization: Basic bWFpbG1hZ2E6Z3Vlc3Q=" そして開いていました。 今回は、このBASE64のコードを探ってみたいと思います。

/* * 2.BASE64って何? */

BASE64って何?私の知識でこの単語が引っかかるのは、 メールで添付フアイルを送る時、BASE64って単語を見たことがある程度です。 よし、Yahoo と Googleで探してみるか。(最近検索結果が違うので探りを兼ねて) GoogleでBASE64をキーワードに探すと、 http://www.google.co.jp/search?hl=ja&ie=UTF-8&q=BASE64&lr=lang_ja (日本語のページを探しました) BASE64とは何か : IT用語辞典 ─ 用語解説 ─ 意味 ... http://e-words.jp/w/BASE64.html が一番上に出てきます。(2004/6/6現在) う〜ん、ここは用語説明でした、、、 上から3つ目に、 BASE64 について http://www.sea-bird.org/doc/Cygwin/BASE64enc.html とサイトがあり、 >1.エンコードすべきデータから、3バイト取得する。 >2.取得した3バイトを24ビットのデータ領域に設定する。 >3.上位から6ビットを取り出し、その数値を下記の変換テーブルに従い >キャラクター文字に変換する。 >4.次の6ビット以降も同じ変換を行い、24ビットすべて変換する。 >5.エンコードすべきデータが無くなるまで、1〜4の作業を繰り返す。 > ※エンコードすべきデータが、2バイトしか無い場合は、それまでBASE64 >エンコード変換した文字列の最終位置に'='を付加する。 > ※エンコードすべきデータが、1バイトしか無い場合は、それまでBASE64 >エンコード変換した文字列の最終位置に'=='を付加する。 > >変換テーブル:6ビットデータの「0〜63」を以下の文字列に変換する。 > 0 〜25:A〜Z > 26〜51:a〜z > 52〜61:0〜9 > 62 :+ > 63 :/ と、丁寧に変換方法が載ってました。 YahooでBASE64を検索しても、いろいろなページがヒットします。 http://search.yahoo.co.jp/bin/query?p=BASE64&hc=0&hs=0 読んでいくと、 6ビット単位にデータを取り出し、それを指定された文字に当てはめる。 って感じです。

/* * 3.さっそく作ってみた */

手抜きで、漢字2バイトには対応していないが、 下記のように作ってみました。 ※なんか無駄に長いんだけど、気にしないでね。 'BASE64の変換処理にチャレンジする 全角文字未対応
Function base64(strMOJI As String) As String

    Dim strWORK As String
    Dim strCODE As String
    Dim n As Integer, i As Integer
    Dim nAMARI  As Integer
    Dim n6BOX(5) As Integer  '6ビット取り出した数値
    Dim nCODE As Integer
    Dim strRET As String
    
    strRET = ""  'リターン値を初期化する
    
    For n = 1 To Len(strMOJI) Step 3
        '3バイトを2進数に変換する、24ビットの数値を作成する
        strWORK = ""
        nAMARI = 0
        For i = 0 To 2
            strCODE = Mid(strMOJI, n + i, 1) '文字を取り出す
            If strCODE = "" Then
                nAMARI = 3 - i
                strWORK = strWORK & "00000000"
                Exit For
            Else  'コードに変換する
                strWORK = strWORK & HEX16toSTR2(Hex(Asc(strCODE)))
            End If
        Next i

        Debug.Print strWORK
        '8*3の24ビット2進数から6ビット単位で4つ取り出し、数値に変換する
        For i = 0 To 3
            n6BOX(i) = Val("&H0" & STR2toHEX16(Mid(strWORK, 1 + i * 6, 6)))
            Debug.Print n6BOX(i)
        Next i
        '対応表にそって変換する
        '6ビットデータの「0〜63」を以下の文字列に変換する。
        '  0 〜25:A〜Z
        '  26〜51:a〜z
        '  52〜61:0〜9
        '  62    :+
        '  63    :/
        For i = 0 To 3 - nAMARI
            If n6BOX(i) = 63 Then strRET = strRET & "/"
            If n6BOX(i) = 62 Then strRET = strRET & "+"
            '  0 〜25:A〜Z
            If 0 <= n6BOX(i) And n6BOX(i) <= 25 Then
                strRET = strRET & Chr(Asc("A") + n6BOX(i) - 0)
            End If
            '  26〜51:a〜z
            If 26 <= n6BOX(i) And n6BOX(i) <= 51 Then
                strRET = strRET & Chr(Asc("a") + n6BOX(i) - 26)
            End If
            '  52〜61:0〜9
            If 52 <= n6BOX(i) And n6BOX(i) <= 61 Then
                strRET = strRET & Chr(Asc("0") + n6BOX(i) - 52)
            End If
        Next i
        'あまりの文字分=を追加する
        If nAMARI = 1 Then strRET = strRET & "="
        If nAMARI = 2 Then strRET = strRET & "=="
    Next n

    base64 = strRET

End Function
'2進文字列を受け取り16進文字列を返す
Function STR2toHEX16(ByVal str2 As String) As String

    Dim strHEX As String
    Dim n As Integer      'ループカウンタ
    Dim i As Integer      'ループのカウンタ
    Dim n8421 As Integer  '8 4 2 1の数値計算用
    Dim nBYTE As Integer

    '頭4文字単位かチェックする
    n = Len(str2) Mod 4      '足りない文字数を計算する
    If n <> 0 Then
       str2 = String(4 - n, "0") & str2 '頭に文字0を追加する
    End If

    strHEX = ""   '結果のエリアを初期化する

    '文字数分ループする
    For n = 1 To Len(str2) Step 4  '4文字(1バイト)単位にループを作る
        n8421 = 8  '初期値に8を代入する(上から計算したいので)
        nBYTE = 0  '1バイト計算用変数を初期化
        For i = 0 To 3  '4回まわるよ(4ビット分)
            'ビットが立っているかチェックする
            If Mid(str2, n + i, 1) = "1" Then
                nBYTE = nBYTE + n8421   'ビットに対応した数値を+する
            End If
            '次のビットを計算したいので2で割る
            n8421 = n8421 / 2
        Next i
        '計算して、1倍との数値が完成したので16進文字にしてセットする
        strHEX = strHEX & Hex(nBYTE)
     Next n

     'リターン値をセットして関数を抜ける
     STR2toHEX16 = strHEX

End Function
'HEX16進文字列を受け取り2進文字列を返す
Function HEX16toSTR2(strHEX As String) As String

    Dim n As Integer      'ループカウンタ
    Dim i As Integer      'ループのカウンタ
    Dim n8421 As Integer  '8 4 2 1の数値計算用
    Dim str2STR As String
    
    Dim nCHK As Integer
    
    str2STR = ""  '結果のエリアを初期化する

    '文字数分ループする
    For n = 1 To Len(strHEX)
        nCHK = CInt("&h" & Mid(strHEX, n, 1)) 'n文字目を数値変換
        n8421 = 8  '初期値に8を代入する(上からチェックしたいので)
        For i = 1 To 4  '4回まわるよ
            If (nCHK And n8421) = 0 Then 'Andでビットをチェックする
                str2STR = str2STR & "0"  'ビットは立ってないよ
            Else
                str2STR = str2STR & "1"  'ビットは立ってるよ
            End If
            '次のビットをチェックしたいので2で割る
            n8421 = n8421 / 2
        Next i
     Next n

     'リターン値をセットして終了
     HEX16toSTR2 = str2STR

End Function
ポイントは、特に無いけど(工夫をしないでダラダラと作ってしまった・・・) ASP系で使った、 2進数文字列を受け取りHEX16進文字列を返す(頭0を+する) http://www.ken3.org/cgi-bin/test/test094-2.asp?DATA=111 と 16進数文字列を2進数文字列へ変換 http://www.ken3.org/cgi-bin/test/test094-1.asp?DATA=F2 を流用して 16進<−−>2進の文字列をやり取りしてます。 ※この変換プログラムのバカな作成秘話は、 愚痴系No.197 テストデータは汚いデータで?(都合の悪いデータで) http://www.ken3.org/guchi/backno/guchi197.html ↑を見て笑ってください・・・ダメだこりゃ・・・ 今回のプログラムの説明に戻ると、 For n = 1 To Len(strMOJI) Step 3 で、3文字単位のループを作り(Step3で3文字飛ばす) '3バイトを2進数に変換する、24ビットの数値を作成する strWORK = "" nAMARI = 0 For i = 0 To 2 strCODE = Mid(strMOJI, n + i, 1) '文字を取り出す If strCODE = "" Then nAMARI = 3 - i strWORK = strWORK & "00000000" Exit For Else 'コードに変換する strWORK = strWORK & HEX16toSTR2(Hex(Asc(strCODE))) End If Next i 上記で、24ビット8ビット*3の2進数文字列を作成し、 そこから、6ビット単位でデータを取り出し、再び数値に変換。 Debug.Print strWORK '8*3の24ビット2進数から6ビット単位で4つ取り出し、数値に変換する For i = 0 To 3 n6BOX(i) = Val("&H0" & STR2toHEX16(Mid(strWORK, 1 + i * 6, 6))) Debug.Print n6BOX(i) Next i ここまでで、6ビット単位の4つの数値が完成する。 で、その数値を、対応表にしたがって、文字に直します。 '対応表にそって変換する '6ビットデータの「0〜63」を以下の文字列に変換する。 ' 0 〜25:A〜Z ' 26〜51:a〜z ' 52〜61:0〜9 ' 62 :+ ' 63 :/ For i = 0 To 3 - nAMARI If n6BOX(i) = 63 Then strRET = strRET & "/" If n6BOX(i) = 62 Then strRET = strRET & "+" ' 0 〜25:A〜Z If 0 <= n6BOX(i) And n6BOX(i) <= 25 Then strRET = strRET & Chr(Asc("A") + n6BOX(i) - 0) End If ' 26〜51:a〜z If 26 <= n6BOX(i) And n6BOX(i) <= 51 Then strRET = strRET & Chr(Asc("a") + n6BOX(i) - 26) End If ' 52〜61:0〜9 If 52 <= n6BOX(i) And n6BOX(i) <= 61 Then strRET = strRET & Chr(Asc("0") + n6BOX(i) - 52) End If Next i ↑オイオイって感じのIf文の羅列ですがご勘弁を。 ↓変換文字が余っていたら=をプラスしてます。 'あまりの文字分=を追加する If nAMARI = 1 Then strRET = strRET & "=" If nAMARI = 2 Then strRET = strRET & "==" Next n と、こんな感じで、3文字単位で変換しました。 ※漢字には非対応なので、2バイト文字を使う人は、一工夫してくださいね。

/* * 4.処理を組み込む */

さて、BASE64の変換処理ができたので、前回のソースに組み込んでみます。 Dim strHEAD As String 'ID:passwordをBASE64変換してヘッダ情報を作成する strHEAD = "Authorization: Basic " & base64("mailmaga:guest") & vbCrLf として、ヘッダ情報を作ってみました。 ※フト、ここにIDとパスワード書いたら丸見えですね(オイオイ) 別な問題があると思いつつ、、、 'BASE64でユーザーID:パスワードを変換して開く
Sub bbbb()

    Dim objIE As Object 'IEオブジェクト参照用
    
    'インターネットエクスプローラーのオブジェクトを作る
    Set objIE = CreateObject("InternetExplorer.application")
    objIE.Visible = True '見えるようにする(お約束)
    
    'テスト用の認証ページに飛ぶ
    Const strURL = "http://www.kurokiya.sake-ten.jp/zzz/"
    Dim strHEAD As String
    
    'ID:passwordをBASE64変換してヘッダ情報を作成する
    strHEAD = "Authorization: Basic " & base64("mailmaga:guest") & vbCrLf
    
    objIE.navigate2 strURL, , , , strHEAD
    
    '表示終了まで待つ
    Do While objIE.Busy = True
        '何もしないループ(笑)
        DoEvents
    Loop

    'テストでHTMLソースを取出す
    Dim strhtml As String
    strhtml = objIE.Document.all(0).innerHTML  '変数に代入
    MsgBox "ソースは" & strhtml & "です"

End Sub

/* * 5.終わりの挨拶 */

BASE64の変換もどきを作ってみました。 でも、パスワードをVBAに埋め込んでおくとキケンだと感じたり・・・ あっ、逆のデコードも書かなきゃ(と将来のネタを残しつつ) http://www.ken3.org/vba/lzh/vba160.lzh にサンプルbase64test.xlsを圧縮しておきます、 Excel2000版ですが使ってみてください。 何か読者の心に残れば、うれしいです。 *私の独り言をうまく消化してくださいね。 いつも失敗?の負け組のKen3でした。 ~~~~~~~(↑オイオイ)


ページフッター

ここまで、読んでいただきどうもです。ここから下は、三流君のホームページの紹介・案内です
目的の情報が見つかったか?少々心配しつつ、、、

種類別のリンク や 広告など

気になったジャンル↓を選択してください。

人気記事(来場者が多いTOP3):
[VBAでIE,WebBrowserを操作]・・・VBAでIE,WebBrowserを操作する サンプルです
[Access から Excel 連携 CreateObject("Excel.Application")]・・・AccessからExcelを操作したりデータの書き出しなどです
[VBAでOutlookの操作 CreateObject("Outlook.Application" )]・・・VBAからOutlookを使い、メール関係を処理するサンプルです
↑上記3つみたいなCreateObjectで他のアプリケーションを操作するサンプルが人気です。

Excel関係:
[Excel UserFormを操作する]・・・エクセルでユーザーフォームを作成して入力などを行ってます
[ExcelからAccessを操作する]・・・ExcelからAccessのマクロを起動してみました、
[Excel関係 関数、その他]・・・その他Excel関係です

Access関係:
[Access UserForm/サブフォーム 操作]・・・アクセスでフォームを使ったサンプルです
[Access レポート操作]・・・レポートを操作してみました
[Access クエリーやその他関数]・・・あまりまとまってませんが、スポット的な単体関数の解説です

その他:VBAの共通関数やテキストファイルの操作など
[VBAでテキストファイル(TextFile)の操作]・・・普通のテキストファイルを使ったサンプルです
[VBA 標準関数関係とその他解説]・・・その他、グダグタ解説してます

開発時の操作: [F1を押してHELPを見る]/ [Debug.Print と イミディエイトウインドウ]/ [実行時エラーでデバッグ]/ [ウォッチ式とSTOP]/ [参照設定を行う]

仕様書(設計書?) XXXX書類: [基本設計書や要求仕様書]/ [テスト仕様書 テストデータ]/ [バグ票]/ [関数仕様書]/ [流れは 入力・処理・出力]

※↑文章の味付けが変わっていて、お口に合うかわかりませんが。。。
※※読んで、気分を悪くされたらスミマセン。

Blogとリンク:[三流君の作業日記]/ [VBAやASPのサンプルコード]/ 広告-[通販人気商品の足跡]



[三流君(TOP ken3.org へ戻る)] / [VBA系TOPへ] / [VBA系バックナンバー目次へ移動]