Base 64エンコーディングは何に使用されますか?


782

「ベース64エンコーディング」については、あちこちで話題になっています。何に使うの?


1
base64_encode()のマニュアルから:「このエンコードは、バイナリデータがメール本文などの8ビットクリーンでないトランスポートレイヤーを介してトランスポートを存続するように設計されています。」
still_dreaming_1

回答:


941

ネットワーク経由で送信したいバイナリデータがある場合、通常、ビットとバイトをそのままの形式でネットワーク経由でストリーミングするだけではそれを行いません。どうして?一部のメディアはテキストのストリーミング用に作成されているためです。わかりません-一部のプロトコルはバイナリデータを制御文字(モデムなど)として解釈する場合があります。または、基礎となるプロトコルが特殊な文字の組み合わせ(FTPが行を変換する方法など)を入力したと見なす可能性があるため、バイナリデータが台無しになる可能性があります。末尾)。

したがって、これを回避するには、バイナリデータを文字にエンコードします。Base64は、これらのタイプのエンコーディングの1つです。

なぜ64なのか?
通常、同じ64文字が多くの文字セットに存在することに依存することができ、データが破損することなくワイヤの反対側に到達することを合理的に確信できるためです。


104
(理論的には、base-80エンコードなどを実行できますが、かなり困難になります。2の累乗は、バイナリの自然なベースです。)
Jon Skeet

13
@yokees:保証はありません。それらはほとんど常に安全な文字です。これが、Base-64の複数の形式がある理由です(en.wikipedia.org/wiki/Base-64)。

8
これは、すべてのネットワークタイプのデータ受け渡しで何らかのエンコードを使用する必要があることを意味しますか?
Tanner Summers

6
しかし、なぜbase64メソッドを使用して文字列データをエンコードするのですか?例:javascript atob関数の場合サーバーがjsonファイルをbase64形式にエンコードする意味はありますか?特殊文字はユースケースになる可能性がありますが、その場合はどうしてutf8ではないのですか?それに関するそれ以上の資源はあなたに大いに感謝されるでしょう。
partizanos 2016

4
誰かが知っているなら、失敗するであろう少なくともいくつかのプロトコルのリストがあればよいでしょう。
Tadej

202

これは基本的に、任意のバイナリデータをASCIIテキストにエンコードする方法です。3バイトのデータごとに4文字が必要で、最後に少しパディングされる可能性があります。

基本的に、入力の各6ビットは64文字のアルファベットでエンコードされます。「標準」アルファベットは、AZ、az、0-9、+および/を使用し、=を埋め込み文字として使用します。URLセーフなバリアントがあります。

ウィキペディアは、かなり多くの情報源です。


PHPのような言語では、バイナリデータはどこから取得されますか。ほとんどの場合、テキストである文字列データを処理します。
Cholthi Paul Ttiopic 16

3
@CholthiPaulTtiopic:暗号化または圧縮の結果、またはサウンド/画像/ビデオ。
Jon Skeet、2016

1
@CholthiPaulTtiopic:「ストレージについて」とはどういう意味かわからないのですが、現時点では、少し話題から外れていると思います。
Jon Skeet、2016

2
@CholthiPaulTtiopic:「文字列バイナリ」の観点から考えることは絶対に避けます。バイナリデータは、テキストとしてではなく、バイナリデータとして扱う必要があります。私は文字通り何百、場合によっては数千のSOに関する質問を見てきましたが、基本的にはこの区別に十分な注意を払っていない人々に要約されます。
Jon Skeet、2016

1
@ still_dreaming_1 PHPはこれを呼び出しますbinary strings。(ソース)php.net/manual/en/function.pack.php
Cholthi Paul Ttiopic


116

これはバイナリデータのテキストエンコーディングであり、結果のテキストには文字、数字、記号「+」、「/」、「=」しかありません。これは、テキストデータ用に特別に使用されるメディアを介してバイナリデータを格納/送信する便利な方法です。

しかし、なぜBase-64なのか?バイナリデータをすぐに思い浮かぶテキストに変換する2つの方法は次のとおりです。

  1. Decimal:各バイトの10進値を3つの数値(045 112 101 037など)として保存します。各バイトは3バイトで表されます。データは3倍に膨れ上がります。
  2. 16進数:バイトを16進数のペアとして格納します:AC 47 0D 1Aなど。各バイトは2バイトで表されます。データは2倍に膨れ上がります。

Base-64は、6ビット(6 x 4 = 24ビット)にまたがる4文字で3バイト(8 x 3 = 24ビット)をマップします。結果は「TWFuIGlzIGRpc3Rpb ...」のようになります。したがって、膨満感は元の4/3 = 1.3333333倍にすぎません。


10
印刷可能なASCII文字に変換できる2の累乗の最大値である64が最適な選択肢であることを正しく理解していますか(95あります)?
voho 2017年

どちらの場合も24ビットの場合、膨れは1:1ではありませんか?または、6ビットにまたがる4文字と言った場合、実際には1文字あたり8ビットですが、最初の2文字には0が埋め込まれているということですか?
David Klempfner、

1
@Backwards_Dave 6ビットはそれぞれ8ビットで表現されます。したがって、膨満感は8:6、つまり4:3です。
Ates Goral

82

すでに述べられていることを除いて、リストされていない2つの非常に一般的な用途は

ハッシュ:

ハッシュは、バイトのブロックを128ビットや256ビット(SHA / MD5)などの固定サイズのバイトの別のブロックに変換する一方向関数です。結果のバイトをBase64に変換すると、特に整合性のチェックサムを比較するときに、ハッシュを表示するのがはるかに簡単になります。ハッシュはBase64で頻繁に見られるため、多くの人々はBase64自体をハッシュと誤解しています。

暗号化:

暗号化キーはテキストではなく生のバイトである必要がないため、Base64が便利なファイルまたはデータベースに保存する必要がある場合があります。結果の暗号化されたバイトと同じです。

Base64は暗号化でよく使用されますが、セキュリティメカニズムではないことに注意してください。誰でもBase64文字列を元のバイトに戻すことができるため、生のバイトをより簡単に表示または保存するためのフォーマットとしてのみ、データを保護する手段として使用しないでください。

証明書

PEM形式のx509証明書はbase 64でエンコードされています。http://how2ssl.com/articles/working_with_pem_files/


4
多くの場合、バイトをバイトとして格納する方が実際には処理が簡単です。データベースでも、特にファイルでも(固定長レコードが使用されている場合、またはバイトが唯一のコンテンツである場合)。通常、Base64は、これらのバイトがどこかに送信されることを意図している場合、特にビットを失うか、バイトの一部を制御コードとして解釈する可能性があるチャネルを介して送信される場合に使用されます。
cHao 2012

符号なし8ビット整数0、1、255、36として書かれたハッシュを見たことがありません。UTF-8または他のエンコードで表示しても意味がありません。base64以外ではどのように表示しますか?暗号化キーと暗号化されたデータは、生のバイトを保存できない構成ファイルとXMLファイルに保存されることがよくあります。どうしてもそれを生のバイトとして保存できるかどうかは同意しますが、base64はそうできない場合に適しています。base64には、送信以外にも多くの用途があります。これらは、2つの一般的なシナリオです。
デスパタール2012

1
ハッシュは10進数ではなく16進数で表示します。ハッシュの場合、それは実際にはbase64よりもはるかに一般的です。
cHao 14

@cHaoはい、これも一般的です。16進数は任意のバイナリデータを表すことができますが、base 64はより多くの文字を使用するため、占有するスペースがはるかに少ないという利点があります。
Despertar 2014

45

数年前、メール機能が導入されたとき、それは完全にテキストベースでしたが、時間が経つにつれて、画像やメディア(オーディオ、ビデオなど)のような添付ファイルの必要性が生じました。これらの添付ファイルがインターネット(基本的にはバイナリデータの形式)経由で送信される場合、バイナリデータが破損する可能性はそのままの形式で高くなります。そこで、この問題に取り組むためにBASE64が登場しました。

バイナリデータの問題は、C、C ++などの一部の言語では文字列の終わりを表すnull文字が含まれているため、NULLバイトを含む未加工の形式でバイナリデータを送信すると、ファイルが完全に読み取られなくなり、データが破損することです。

例えば ​​:

CおよびC ++では、この「ヌル」文字はストリングの終わりを示します。したがって、「HELLO」は次のように保存されます。

こんにちは

72 69 76 76 79 00

00は「ここでストップ」と言います。

それでは、BASE64エンコーディングの仕組みについて詳しく見ていきましょう。

注意点:文字列の長さは3の倍数でなければなりません。

例1:

エンコードする文字列:「ace」、Length = 3

1)各文字を10進数に変換します。

a = 97、c = 99、e = 101

ここに画像の説明を入力してください

2)各10進数を8ビットの2進数表現に変更します。

97 = 01100001、99 = 01100011、101 = 01100101

組み合わせ:01100001 01100011 01100101

3)6ビットのグループに分けます。

011000 010110 001101 100101

4)2進数から10進数への計算

011000 = 24、010110 = 22、001101 = 13、100101 = 37

5)base64チャートを使用して、10進文字をbase64に変換します。

24 = Y、22 = W、13 = N、37 = l

「ace」=>「YWNl」

ここに画像の説明を入力してください

例2:

エンコードされる文字列:「abcd」長さ= 4、3の倍数ではありません。文字列の長さを3の倍数にするには、2ビットのパディングを追加して長さ= 6にする必要があります。パディングビットは「=」記号で表されます。

注意点:1つのパディングビットは2つのゼロ00に等しいため、2つのパディングビットは4つのゼロ0000に等しくなります。

だからプロセスを始めましょう:–

1)各文字を10進数に変換します。

a = 97、b = 98、c = 99、d = 100

2)各10進数を8ビットの2進数表現に変更します。

97 = 01100001、98 = 01100010、99 = 01100011、100 = 01100100

3)6ビットのグループに分けます。

011000、010110、001001、100011、011001、00

したがって、最後の6ビットは完全ではないため、4つのゼロ「0000」に等しい2つのパディングビットを挿入します。

011000、010110、001001、100011、011001、000000 ==

今、それは同じです。末尾の2つの等号は、4つのゼロが追加されたことを示しています(デコードに役立ちます)。

4)2進数を10進数に計算します。

011000 = 24、010110 = 22、001001 = 9、100011 = 35、011001 = 25、000000 = 0 ==

5)base64チャートを使用して、10進文字をbase64に変換します。

24 = Y、22 = W、9 = j、35 = j、25 = Z、0 = A ==

「abcd」=>「YWJjZA ==」


5
これは本当に素晴らしい説明です
maheshmnj

28

コンピュータの初期の頃は、電話回線のシステム間通信が特に信頼性に欠けていたため、データの整合性を検証するための迅速で汚れた方法である「ビットパリティ」が使用されていました。この方法では、送信されるすべてのバイトに7ビットのデータがあり、8バイト目は1または0になり、バイトの1ビットの総数が偶数になるようにします。

したがって、0x01は0x81として送信されます。0x02は0x82になります。0x03は0x03のままになります。

このシステムをさらに進めるために、ASCII文字セットが定義されたとき、00-7Fだけに文字が割り当てられました。(現在でも、80〜FFの範囲で設定されたすべての文字は非標準です)

今日の多くのルーターは、パリティチェックとバイト変換をハードウェアに組み込んでおり、ルーターに接続されているコンピューターが7ビットデータを厳密に処理するように強制しています。これにより、電子メールの添付ファイル(およびその他のすべてのデータ、つまりHTTPおよびSMTPプロトコルがテキストベースである理由)がテキストのみの形式に強制的に変換されます。

90年代に生き残ったルーターはほとんどありません。どれも今日使われているのではないかと思う。


2
これは素晴らしい議論のポイントであり、興味深い歴史のレッスンです。
Dan Bechard、2015年

26

http://en.wikipedia.org/wiki/Base64から

Base64という用語は、特定のMIMEコンテンツ転送エンコーディングを指します。また、バイナリデータを数値で処理し、base 64表現に変換することでバイナリデータをエンコードする同様のエンコードスキームの総称としても使用されます。ベースの特定の選択は、文字セットエンコーディングの履歴によるものです。64文字のセットを選択できます。これは、ほとんどのエンコーディングに共通するサブセットの一部であり、印刷も可能です。この組み合わせにより、従来は8ビットクリーンではなかった電子メールなどのシステムを介した転送中にデータが変更される可能性は低くなります。

Base64はさまざまなコンテキストで使用できます。

  • EvolutionとThunderbirdはBase64を使用して電子メールのパスワードを難読化しています[1]
  • Base64を使用して、区切り記号の衝突を引き起こす可能性のあるテキストを送信および保存
  • Base64は、暗号化キー管理のオーバーヘッドを発生させることなく、秘密を覆い隠すための迅速かつ安全ではないショートカットとしてよく使用されます

  • スパマーは、Base64を使用して基本的なスパム対策ツールを回避します。このツールは、多くの場合、Base64をデコードしないため、エンコードされたメッセージ内のキーワードを検出できません。

  • Base64は、LDIFファイル内の文字列をエンコードするために使用されます
  • Base64は、バイナリファイルをXMLファイルに埋め込むために使用されることがあります。たとえば、Firefoxのbookmarks.htmlのような構文を使用します。
  • Base64は、政府の会計署名印刷デバイスと通信する場合にも使用され(通常、シリアルポートまたはパラレルポートを介して)、署名用のレシート文字を転送するときの遅延を最小限に抑えます。
  • Base64は、スクリプト内のイメージなどのバイナリファイルをエンコードして、外部ファイルに依存しないようにするために使用されます。
  • raw-imageデータをbackground-imageなどのCSSプロパティに埋め込むために使用できます。

11

一部のトランスポートプロトコルでは、英数字のみを送信できます。特別なアクションをトリガーするために制御文字が使用されている状況や、1文字あたりのビット幅が制限されている状況を想像してみてください。BASE64は、英数字のみを使用して符号化に任意の入力を変換し+/及び=パディング文字として。


9

ここで説明するBase64の使用法は、ややハックです。したがって、ハッキングが嫌いな場合は、続行しないでください。

MySQLのutf8は3バイトバージョンのutf8を使用しているため、4バイトのUnicode文字をサポートしていないことを発見したとき、問題に遭遇しました。では、MySQLのutf8で完全な4バイトのユニコードをサポートするために何をしたのでしょうか。さて、base64はデータベースに格納するときに文字列をエンコードし、base64は取得するときにデコードします。

base64エンコードとデコードは非常に高速なので、上記は完全に機能しました。

次の点に注意してください。

  • Base64エンコーディングは33%多いストレージを使用します

  • データベースに保存された文字列は人間が読める形式にはなりません(データベース文字列が基本的な形式の暗号化を使用する機能として販売することもできます)。

上記の方法は、Unicodeをサポートしていないストレージエンジンに使用できます。


6
「データベース文字列が基本的な形式の暗号化を使用する機能としてそれを売ることができます」私はあなたのスタイルが好きです:D
Ercan

8
「データベース文字列が基本的な形式の暗号化を使用するという機能としてそれを売ることができる」なんて恐ろしいことを言っている:D
Alex

1
base64デコードアルゴリズムroflを持たない人に対する基本的な暗号化形式rofl:D
Eladian

1
@Alexまったく「言うのは恐ろしいこと」ではありません。2次の機密データは、データベース管理者が読み取れないようにbase64でエンコードしても問題ありません。すべてのデータに対して常に最高レベルの暗号化を行う必要はありません。たとえば、データベース管理者から「コメント」を非表示にする場合、base64がジョブに適しています。グラチャス!
バジルムーサ

1
MySQLがすべてのUnicodeをサポートするようになりましたが、後方互換性のために、そのutf8型はまだ3バイトのみです。本物が必要な場合はを使用してくださいutf8mb4。素晴らしいハックですが、もう必要ありません。
TRiG 2018

7

任意のバイナリデータをASCIIテキストに変換するために使用されます。

たとえば、電子メールの添付ファイルはこの方法で送信されます。


7

Webサービスを介して大きなバイナリオブジェクト(画像)を転送する場合、私は実用的な意味で使用します。そのため、Pythonスクリプトを使用してC#Webサービスをテストしているときに、少し魔法をかけてバイナリオブジェクトを再作成できます。

[パイソンで]

import base64
imageAsBytes = base64.b64decode( dataFromWS )

1
データはより速く移動しますか?
FelipeM 2017

@FelipeMは遅く、速くはありません。Base64には33%のオーバーヘッドがあります(安全のため)
Juraj

6

「Base64エンコードスキームは、テキストデータを処理するように設計されたメディアに保存および転送する必要があるバイナリデータをエンコードする必要がある場合に一般的に使用されます。これは、転送中にデータが変更されることなくそのままであることを保証するためです」(Wiki、2017)

例は次のようになります。ASCII文字のみを受け入れるWebサービスがあります。ユーザーのデータを保存して他の場所(API)に転送したいが、受信者はそのままのデータを受信したい。Base64はそのためです。。。唯一の欠点は、base64エンコーディングが通常の文字列よりも約33%多くのスペースを必要とすることです。

別の例:: uenc = url encrypted = aHR0cDovL2xvYy5tYWdlbnRvLmNvbS9hc2ljcy1tZW4tcy1nZWwta2F5YW5vLXhpaS5odG1s = http://loc.querytip.com/asics-men-s-gel-kayano-kayano-kayano-kayano

ご覧のとおり、最後にアクセスしたURLをパラメーターとして送信する場合、URLに文字「/」を含めることはできません。これは、「MOD rewrite」の属性/値のルールを破るからです– GETパラメーター。

完全な例は次のようになります:“ http://loc.querytip.com/checkout/cart/add/uenc/http://loc.magento.com/asics-men-s-gel-kayano-xii.html/product / 93 /


4

ほとんどの場合、ASCII(または単純な)文字セットのみを処理できるコンテキストでバイナリデータをエンコードするために使用されるのを見てきました。


3

ブラッドが言っていることを少し拡張します:電子メールやUsenetの多くの転送メカニズムやデータを移動する他の方法は「8ビットクリーン」ではありません。 0x0Dはキャリッジリターンと見なされ、キャリッジリターンとラインフィードに変換されます。Base 64は、すべてのバイナリ文字をいくつかの標準のASCII文字と数字および句読点にマップするため、このように変換されません。


2

Base64

Base64は、バイナリデータを数値で処理し、base 64表現に変換することでバイナリデータをエンコードする、いくつかの類似したエンコードスキームの総称です。Base64用語は、特定のMIMEコンテンツ転送エンコーディングに由来します。

Base64エンコードスキームは、テキストデータを処理するように設計されたメディアを介して保存および転送する必要があるバイナリデータをエンコードする必要がある場合に一般的に使用されます。これは、転送中にデータを変更せずにそのまま維持するためです。Base64は、MIMEを介した電子メールを含む多くのアプリケーションで一般的に使用され、XMLで複雑なデータを保存します。


0

Base64は多くの目的に使用できます。

主な理由は、バイナリデータを適切なものに変換するためです。

あるサイトから別のサイトにJSONデータを渡したり、ユーザーに関するCookieに情報を格納したりするために、私は時々それを使用します。

注:暗号化に「使用」することはできます-簡単に破ることができて眉をひそめられるかもしれませんが、暗号化に使用できないと人々が言っ​​ている理由はわかりません。暗号化とは、あるデータ文字列を、後で復号化できるかどうかに関係なく別のデータ文字列に変換することだけを意味します。これが、base64が行うことです。



2
あなたは、「暗号化」の定義を解釈しているこれまであまりにも文字通り。言葉はその起源よりもかなり具体的なものに進化しました。
Dan Bechard、2015年

0

16進数の1桁は1ニブル(4ビット)です。2つのニブルは8ビットになり、1バイトとも呼ばれます。

MD5は128ビットの出力を生成します。これは、32 * 4 = 128ビットである一連の32桁の16進数を使用して表されます。128ビットは16バイトになります(1バイトが8ビットであるため)。

各Base64文字は6ビットをエンコードします(2、4、または6ビットをエンコードできる最後の非パッド文字、および存在する場合は最後のパッド文字を除く)。したがって、Base64エンコードごとに、128ビットハッシュには少なくとも「128/6」= 22文字と、必要に応じてパッドが必要です。

base64を使用して、目的の長さ(6、8、または10)のエンコードされた出力を生成できます。8文字長の出力を決定することを選択した場合、それは8バイトしか占有しませんが、128ビットのハッシュ出力では16バイトを占有していました。

そのため、セキュリティに加えて、base64エンコーディングを使用して、消費されるスペースを削減します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.