https://qiita.com/PlanetMeron/items/2905e2d0aa7fe46a36d4


base64ってなんぞ??理解のために実装してみた

base64とは

base64という言葉を聞いたことがあるでしょうか??
base64とは、64進数を意味する言葉で、すべてのデータをアルファベット(a~zA~z)と数字(0~9)、一部の記号(+,/)の64文字で表すエンコード方式です
ただ、データ長を揃えるためにパディングとして末尾に記号の=を使用するので、厳密にはbase64は、65文字の英数字から表現されます
(URLや正規表現のなかでbase64を用いると一部の記号(+,/)は特別な意味を持つことがあるので-_などが用いられることがあります)

なぜbase64をつかうの??

かつての電子メールを送るためのプロトコルSMTPでは、ASCIIといわれる7bitで表現される英数字しか送ることができませんでした
したがって、メールを使って画像や音声などのデータをやりとりしたいと思った時に、英数字しか対応していないSMTPでは、それらのデータを送受信することができませんでした

そこで、すべてのデータを英数字で表すMIME(Multipurpose Internet Mail Extensions)という規格が登場し、その中でbase64というデータの変換方法が定められました
これによって、受信側と送信側がMIMEに則ってエンコード・デコードをすることで、メールを通して画像や音声などの送受信が可能になりました

現在では、JSONなどで特殊文字を含まないように画像データをbase64でエンコードしたり、Webページの表示の際にリクエスト数を減らすためにbase64でエンコードした画像をhtmlにそのまま埋め込むなどの用途で用いられています

base64実装してみた

どの言語にもbase64はサポートされていて、base64の実装をする必要はほとんどありませんが、エンコードの原理の理解を含めて実装してみようと思います

base64の変換方式

base64における処理を簡潔にいうと、
エンコードしたいファイルのバイナリデータを6bitずつ取り出し(足りない分は0を追加する)、
6ビットとAscii文字の変換表を用いて、4文字ずつにする(4文字に満たない場合は=を追加する)

変換アルゴリズム

ここでは、文字列をバイナリ化し、base64でエンコードする例を通して、具体的な処理手順について確認をします

処理手順を以下に示します

1. 変更したい文字列をバイナリ(2進数)に変換する

変換したい文字列"abcdefg"
→0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67(16進数)
→0110 0001, 0110 0010, 0110 0011, 0110 0100, 0110  0101, 0110 0110, 0110 0111(2進数)

2. バイナリを6ビットづつに分割

011000, 010110, 001001, 100011, 011001, 000110, 0101 01, 100110, 011001,11

3. 最後の2ビットが余るので,6ビットになるように0を追加する

011000, 010110, 001001, 100011, 011001, 000110, 0101 01, 100110, 011001, 110000

4. 下図に示す変換表よりビットを文字に変換する

Y W J j Z G V m Z w

5. 4文字に分けた時に、2文字分足りないので=を追加する

YWJj ZGVm Zw==

6. base64の文字列の完成

"YWJjZGVmZw=="

~base64のビット列と英数字の変換表~

10進2進文字10進2進文字10進2進文字10進2進文字
0000000A16010000Q32100000g48110000w
1000001B17010001R33100001h49110001x
2000010C18010010S34100010i50110010y
3000011D19010011T35100011j51110011z
4000100E20010100U36100100k521101000
5000101F21010101V37100101l531101011
6000110G22010110W38100110m541101102
7000111H23010111X39100111n551101113
8001000I24011000Y40101000o561110004
9001001J25011001Z41101001p571110015
10001010K26011010a42101010q581110106
11001011L27011011b43101011r591110117
12001100M28011100c44101100s601111008
13001101N29011101d45101101t611111019
14001110O30011110e46101110u62111110+
15001111P31011111f47101111v63111111/

プログラムで作ってみた

以下のプログラムの実行には、変換表(base64_table.json)が必要なので別途、ダウンロードして使ってください

string2base64.py
#!/usr/bin/env python

import sys
import json

# 1文字が8バイトで表される
BYTE_SIZE = 8

# 文字列textをバイナリの文字列に変換する
def str2bin(s):
    binStr = ""

    #ord関数で文字をASCIIコードへ変換し、
    #シフト演算で各桁のビットを取り出す
    for c in s:
        for i in range(BYTE_SIZE):
            binStr += str((ord(c) >> (BYTE_SIZE - (i + 1))) & 1)
    return binStr

# 文字列sを文字数nで分割したリストを返す
# (例)
# split("abcdef", 2) => [["ab"], ["cd"], ["ef"]]
def split(s, n):
    return [s[i:i+n] for i in range(0, len(s), n)]


# 文字列sを文字数nで分割した時に足りない部分を文字cで埋める
# (例)
# fillInBlank("abcd", 6, "=") => "abcd=="
def fillInBlank(s, n, c):
    mod = len(s) % n

    # 割り切れた場合は何も処理をしない
    if mod == 0: return s 

    # 割り切れなかった場合、残りの部分を埋める
    margin = n - mod
    return s + c * margin

# main関数         
def main():

    # コマンドの引数を受け取る
    argvs = sys.argv
    argc = len(argvs)

    # 引数が1つじゃなかったら無かったら、処理をせず終了
    if argc != 2:
        print "Usage:\n$ python %s CONVERT_STRING" % argvs[0]
        quit()

    # 1. 文字列をバイナリ文字列に変換
    binStr = str2bin(argvs[1])

    # 2. バイナリを6ビットづつに分割
    splitCount  =6
    s = split(binStr, splitCount)

    # 最後の2ビットが余るので,6ビットになるように0を追加する
    s[-1] = fillInBlank(s[-1], 6, "0")

    # 変換表の辞書を読み込み
    tableFile = open("base64_table.json", "r")
    base64Dict = json.loads(tableFile.read())

    result = ""

    for i in s:
        result += base64Dict[i]

    print result

    print fillInBlank(result, 4, "=")

if __name__ == '__main__':
    main()

ファイルの実行

文字列"abcdefg"を引数としてpythonファイルを実行すると次のような結果がでます

Terminal
$ python string2base64.py abcdefg
binary:  01100001011000100110001101100100011001010110011001100111
base64:  YWJjZGVmZw==

WEB便利ツールさんのように、外部ツールと同じ結果を得ることができたので、成功です!!

まとめ

文字列をBase64でエンコードするのは、そもそもの用途からは離れてしまうのですが、確認のために実装を行いました。

車輪の再発明ですが、理解ができて、思った通りに結果になるのは楽しいですね!!

参考文献


https://opentutorials.org/course/228/4894

ビルド (build)とは

プログラムの元ネタ(ソースコード)をあれやこれやして実際のプログラムを作る作業のこと
(인간이 인식할 수 있는 java,python 등과 같은 프로그래밍 언어를 컴퓨터가 이해하는 바이너리로 변환하기 위해 필요한 컴파일 + @의 작업
->더쉽게 표현하면, 프로그램을 실행시키기 위한 사전 준비)
です。

image piyo

 詳しく書くよ

プログラマさんがえっちらおっちらと作ったプログラムの元ネタ(ソースコード)から、実際に動くプログラムを作り出す作業がビルドです。

私は専門外の方に説明するとき、プログラムができるまでの流れを

1.人間語でプログラムの元ネタ(ソースコード)を書く
2.ソースコードを人間語から機械語に翻訳する(コンパイル
3.コンピュータさんが翻訳された指示に従ってお仕事する(実行)


と説明します。

ビルド

ですが、この説明は、厳密には正しくありません。
元ネタから実際のプログラムを作る際には、もう少しいろいろな作業が必要です。

この「もう少しいろいろな作業」も含めて「プログラムの元ネタから実際のプログラムを作る作業」がビルドです。
「コンパイル」(元ネタを人間語から機械語に翻訳する作業)と同じ意味で使われる場合もありますが、実際には「コンパイル+α」な作業を指します。

例えば、そうですね。

ピヨ太君は自分でケーキを作って自分でケーキを食べる「なんちゃってピヨ子さん」プログラムを作ることにしました。
本物のピヨ子さんはケーキを食べるだけで、作るのは他人任せです。
本物よりも優秀ですね。

ビルド2

この「なんちゃってピヨ子さん」プログラムですが、やることは

1.ケーキを作る
2.ケーキを食べる


の2つです。

この2つの処理をまとめて書いても良いのですが、ピヨ太君は分けることにしました。
「ケーキを作る」と「ケーキを食べる」を別々に用意し、それを合体させることで「ケーキを作って食べる」プログラムにするのです。

ビルド3

具体的には、まずは「ケーキを作る」処理を書いた元ネタと「ケーキを食べる」処理を書いた元ネタを別のファイルとして用意します。

ビルド4

次に、それぞれのファイルをコンパイル(人間語から機械語に翻訳)して、コンピュータさんが読める状態にします。

ビルド5

最後に、この2つを合体します。
これで「ケーキを作って食べる」ことのできる「なんちゃってピヨ子さん」プログラムができあがりました。

ビルド6

この作業がビルドです。
用意された「ケーキを作る」処理を書いた元ネタと「ケーキを食べる」元ネタから、最終的な「なんちゃってピヨ子さん」プログラムを作り上げるまでの工程を指します。

……というのが基本です。
プログラミング言語によっては、それに加えて、ドキュメントっぽい何かを作ったり、他の人に配る用のファイルを作ったりもしてくれます。

具体的に何をやってくれるかの細かい違いは、ビルド作業をやるプログラムに依存します。
当たり前ですが、実際のビルドは人間様の手でやるわけではありません。
人間様がやるのは、せいぜい「ビルドしてくださいボタン」を押すとか「ビルドしますよプログラム」を起動するくらいでしょう。
コンピュータの中にはビルドをするのがお仕事のプログラムがいて、そいつの手によってビルドされる(元ネタから実際のプログラムが作られる)のです。

image piyo2

 一言でまとめるよ

まぁ「ビルド」って単語が出てきたら「プログラムの元ネタから実際のプログラムを作る作業なんだな~」と、お考えください。

'C Lang > 버리기는 아까운 IT잡지식' 카테고리의 다른 글

tcp프로토콜과 udp프로토콜  (0) 2019.06.04
tcp/ip프로토콜의 전반적인 흐름 설명  (0) 2019.06.04
base64 란 뭘까?  (0) 2019.01.21
https와 ssl  (0) 2018.12.23
라인 리치메뉴 만들기  (0) 2018.07.05

1. line@manager 페이지 열기

https://admin-official.line.me/ 접속해 하위화면을 보면, 라인 디벨로퍼에서 설정한 챗봇목록이 보인다.

내가 리치메뉴를 설정하고 싶은 챗봇을 선택



2. rich contects 작성하기

  1. 좌측 메뉴 리스트에서 리치컨텐츠작성 선택
  2. 하단으로 이동하면 메뉴를 선택할 수 있는 디자인가이드가 몇개 나오는데 이때 주의해야 할점은 메뉴 하나하나에 이미지를 주는 것이 아니고, 메뉴에 선이 그어져 있는 듯한 이미지 하나만 설정한다는 것(뭔말인지 이해못한다면 아래 이미지를 참고)


  3. 컨텐츠설정

    ・키워드
    선행작업①

    메세지 -> 키워드 응답 메세지 페이지에서 어떤 패턴으로 응답할지를 설정해주어야한다

    이때 텍스트 스탬프 화면 쿠폰 등 다양한 응답을 하게 할 수 있다.

    선행작업②

    라인 디벨로퍼 봇설정 페이지에서 LINE@機能の利用 -> 자동응답 메세지를 이용함으로 설정해야 키워드가 반환된다.


    ・url

    url을 지정할시 유저가 해당 영역을 클릭하면 url이 열린다.


    ・텍스트

    라인봇이 지정된 텍스트를 반환한다.















+ Recent posts