Base64 エンコーディングのナレッジ レコード

目次

コーディング手順

エンコーディング

サイズの増加

= 等号

デモ


コーディング手順

Base64と はバイナリデータを64個の印字可能な文字で表現する表現方法で、2^6=64なので6ビットが1単位で、ある印字可能な文字に対応します。

Base64 は、  MIME 電子メールや XML の複雑なデータなど、テキスト データが通常処理される状況で、一部のバイナリ データを表現、送信、および保存するためによく使用されます。

プロジェクトでバイト配列と文字列の変換を扱う場合、文字セットを指定しないと、後のデモで説明するように、文字配列の長さが変わります。

Base64 エンコーディングでは、3 つの 8 ビット バイト (3*8=24) を 4 つの 6 ビット バイト (4*6=24) に変換し、6 ビットの前に 2 つの 0 を追加して 8 ビット ワード セクション形式を形成する必要があります。 . 残りの文字が 3 バイト未満の場合は 0 で埋められ、出力文字は = を使用するため エンコードされた出力テキストの末尾に 1 または 2 = が表示される場合があります。

出力コード ビットが読み取り可能な文字であることを確認するために、Base64 は 統一変換用のコード テーブルを策定しました。エンコーディング テーブルのサイズは 2^6=64であり、これが Base64 という名前の由来でもあります。

Base64  で印刷可能な文字には、 文字AZaz、および数字 0-9が含まれているため、合計で 62 文字であり、2 つの印刷可能な記号は異なるシステムでは異なります ( および ) +/,还有=

Base64 はインデックス エンコーディングであり、各文字はインデックスに対応しています。具体的な関係図は次のとおりです。

エンコーディング

64 は 2 の 6 乗に等しいため、Base64 文字は実際には 6 バイナリ ビット (ビット) を表します。
ただし、バイナリデータの 1 バイトは 8 ビットに相当するため、3 バイト (3 x 8 = 24 ビット) の文字列/バイナリデータは、4 つの Base64 文字 (4 x 6 = 24 ビット) に変換できます。
なぜ 3 バイトのグループなのですか? 6 と 8 の最小公倍数は 24 なので、24 ビットはちょうど 3 バイトです。

特定のエンコード方法:

  1. 各 3 バイトをグループとして扱い、合計 24 バイナリ ビットで 3 バイトを扱います。

  2. これらの 24 ビットをそれぞれ 6 ビットの 4 つのグループに分割します。

  3. 2 進数 6 桁の各グループの前に 2 つの 00 を追加して、2 進数 32 桁、つまり 4 バイトに拡張します。

  4. 各バイトは、文字数である 64 未満の数に対応します。

  5. 文字インデックス関係テーブルによると、各文字番号は文字に対応し、Base64 でエンコードされた文字が取得されます。

 

 上図 の文字列を 'you'変換すると、 のようにエンコードされます 'eW91'

サイズの増加

3文字をBase64でエンコードすると、最終的に4文字になることがわかります。各 6 ビットは 2 つの 0 で埋められるため、1 バイトに対応する 8 ビットになります。
これはちょうど 3 分の 1 であるため、通常の状況では、Base64 でエンコードされたデータの量は、通常、元のデータの量よりも 3 分の 1 大きくなります

= 等号

3 文字の英字を 4 つの Base64 文字に変換できます。文字の長さが 3 の倍数でない場合、どのような規則を使用すればよいでしょうか。
実はこれも単純で、実際に Base エンコーディングを使ってみると、65 番目の文字が記号であることがよくありますが、 '=' この等号は、この特殊な状況の処理方法です。
3 バイト未満の場所では、24 バイナリ ビットになるまで末尾に 0 が追加されます。
ただし、バイト数を計算するときは、合計の長さが直接 3 で除算されることに注意してください。余りが 1 の場合は末尾に 1 が追加され、余りが 2 の場合は 2 が追加され=ます=
したがって、トランスコードされた文字列には、次の図に詳細が示されているように、1 または 2 のいずれかの接尾辞の等号を追加する必要があります。

図の2番目は、 'd'インデックス文字テーブルでインデックス0を区別するために単一の文字を使用しています.このとき、取得されたコードでは、インデックス0に対応するA文字があります'='が 文字を追加します.

デモ

package com.cjian.security;


import com.sun.org.apache.xerces.internal.impl.dv.util.Base64;

import java.security.SecureRandom;

/**
 * @Author: cjian
 * @Date: 2022/11/9 17:09
 * @Des:
 */
public class Base64Demo {
    public static Base64 base64 = new Base64();

    public static void main(String[] args) {
        String man = base64.encode("you".getBytes());
        System.out.println("you的base64结果:"+man);

        SecureRandom secureRandom = new SecureRandom();
        byte[] randomBytes = new byte[16];
        secureRandom.nextBytes(randomBytes);

        String str = new String(randomBytes);
        System.out.println("原值:" + str);
        //问题来了,长度发生了变化
        //如果转string和获取字节的时候指定ISO-8859-1就没有问题
        System.out.println("原值转byte长度:"+str.getBytes().length);

        String r = base64.encode(randomBytes);
        System.out.println("base64后:" + r);

        String str2 = new String(base64.decode(r));
        System.out.println("base64编码:" + str2);
        System.out.println("base64解码后byte长度:" + base64.decode(r).length);
    }

}

出力: 

you的base64结果:eW91
原值:�;Ķp�K�n�ώ�|/
原值转byte长度:26
base64后:1DvEtnCSS55uFMPPjqp8Lw==
base64编码:�;Ķp�K�n�ώ�|/
base64解码后byte长度:16

おすすめ

転載: blog.csdn.net/cj_eryue/article/details/127774474