base 64の符号化復号及びsun.misc.BASE 64 Decoderの使い方
7989 ワード
一、Base 64とは何ですか。
RFC 2045の定義に従って、Base 64は、Base 64コンテンツ転送符号化が、任意のシーケンスの8ビットバイトを直接認識されにくい形式として記述するように設計されていると定義される.(The Base64 Content-Transfer-Encoding is designed to represent arbitrary sequences of octets in a form that need not be humanly readable.)
二、なぜBase 64を使うのですか。
このコードを設計するとき、設計者が一番考えていると思います.
3
質問:
1.
暗号化しますか?
2.
暗号化アルゴリズムの複雑さと効率
3.
転送の処理方法
暗号化は肯定的ですが、暗号化の目的はユーザーに非常に安全に送信させることではありません.
Email
.この暗号化方式は主に
“
君子を防ぎ小人を防ぐ
”
.一目で見ても内容が全く見えないようにすればいい.
この目的に基づいた暗号化アルゴリズムの複雑さと効率もあまり大きくも低くはできない.前の理由と同様に、MIMEプロトコルなどのEmailを送信するためのプロトコルは、どのように安全にEmailを送受信するかではなく、どのようにEmailを送受信するかを解決します.そのためアルゴリズムの複雑さは小さく、効率が高い.そうしないと、Emailを送信するために資源を大量に占有し、道が少し歪んでしまう.
しかし、上記の2点に基づいている場合、最も簡単なシーザー法を使用すればよいのですが、なぜBase 64はシーザー法より複雑に見えるのでしょうか.これは、Emailの転送中に、履歴上の理由により、EmailはASCII文字、すなわち8ビットバイトの下位7ビットの転送しか許可されないためである.したがって、ASCII以外の文字(バイトの最上位が1)を持つEmailが「履歴の問題」のあるゲートウェイを通過すると、問題が発生する可能性があります.ゲートウェイは最高位置を0にする可能性があります!明らかに、問題はこのように発生しました!そのため、メールを正常に送るためには、この問題を考えなければなりません!だから、アルファベットの位置を変えるシーザーなどの案だけではだめだ.この点についてはRFC 2046を参照することができる.
以上のいくつかの要因に基づいてBase 64符号化が生成される.
三、Base 64アルゴリズムの詳細
Base64
コード要求
3
個
8
ビットバイト(
3*8=24
)から
4
個
6
ビットのバイト(
4*6=24
)、の後に
6
位の前に2つ補充する
0
形成する
8
ビット1バイトの形式.
具体的な変換形式は以下の図を参照してください.
文字列
張
3” 110101
01 11000101 00110011
00110101 00011100 00010100 00110011
表1
このように考えることができます:
8
ビットのバイトが一連に連なる
110101011100010100110011
そして毎回順番に選択
6
個出てからこれを
6
バイナリ数の前にもう2つ追加
0(表1の00)
で、新しいバイトになりました.あとで選ぶ
6
個来て、更に追加します
0
ああ、このように押して、
24
個のバイナリ数がすべて選択されました.
実際の結果を見てみましょう.
文字列
“
張
3”
11010101 11000101 00110011
HEX: D5 HEX: C5 HEX: 33
00110101 00011100 00010100 00110011
文字'5'文字'^'文字'^T'文字'3'
十進法53十進法34十進法20十進法
51
表
2
このように
“
張
3 ”
この文字列は
Base64
として表示
”5^\^T3”
もういいですか.の間違いだ!
Base64
符号化方式は,単に変換されたコンテンツを用いて符号化するものではない.像
’^\’
文字は制御文字であり、コンピュータでは表示されず、場合によっては使用できません.
Base64
独自のエンコーディング・テーブルがあります.
The Base 64 Alphabet(文字マッピングテーブル)
Value
Encoding
Value
Encoding
Value
Encoding
Value
Encoding
0
A
17
R
34
i
51
z
1
B
18
S
35
j
52
0
2
C
19
T
36
k
53
1
3
D
20
U
37
l
54
2
4
E
21
V
38
m
55
3
5
F
22
W
39
n
56
4
6
C
23
X
40
o
57
5
7
H
24
Y
41
p
58
6
8
I
25
Z
42
q
59
7
9
J
26
a
43
r
60
8
10
K
27
b
44
s
61
9
11
L
28
c
45
t
62
+
12
M
29
d
46
u
63
/
13
N
30
e
47
v
(pad)
=
14
O
31
f
48
w
15
P
32
g
49
x
16
Q
33
h
50
y
表3
これもBase 64名の由来であり、Base 64符号化の結果、アルゴリズムによって符号化が上位2桁が0で下位6になることを代表データとするのではなく、上の表のように「A」が7桁、「a」が6桁になる.表では,符号化された番号は,得られた新しいバイトの10進数値に対応する.従って、テーブル2から対応するBase 64符号化が得られる.
文字列
“
張
3”
11010101 11000101 00110011
HEX:D5 HEX:C5 HEX:33
00110101 00011100 00010100 00110011
文字
’5’
文字
’^\’
文字
’^T’
文字
’3’
じっしん
53
じっしん
34
じっしん
20
じっしん
51
文字
’1’
文字
’i’
文字
’U’
文字
’z’
表
4
このように、文字列
“
張
3”
エンコードされて文字列になります
“1iUz”
しました.
Base64
将
3
バイトから
4
このため、符号化後の符号量(バイト単位、以下同)は符号化前の符号量よりも約多くなる
1/3
.なぜかというと
“
約
”
あ、コード量がちょうど
3
の整数倍になると、自然と多くなります.
1/3
.でもそうじゃなかったら?
注意深い人はもう気づいたかもしれませんが、
TheBase64 Alphabet
の最後に
(pad)=
文字.この文字の目的はこの問題を処理することです.
コード量が
3
の整数倍の場合、コード量
/3
の余りはもちろん
2
または
1
.変換するとき、結果が足りない
6
ビットの使用
0
該当する位置を補い、その後
6
位の前に2つ補充する
0
.空振りした結果を変換して使います
“=”
補位に来る.例えば結果が最後に残ったら
2
バイト
“
張
”
:
文字列
“
張
”
11010101 11000101
HEX:D5 HEX:C5
00110101 00011100 00010100
じっしん
53
じっしん
34
じっしん
20 pad
文字
’1’
文字
’i’
文字
’U’
文字
’=’
表
6
こうして、最後の
2
バイトが整理されて
“1iU=”
.
同様に、元のコードが1バイトしか残っていない場合は、2つ追加されます.
“=”
.この2つのケースしかないので、
Base64
のエンコーディングは、エンコーディングの最後に2つまであります.
“=” .
将に至っては
Base64
の復号化は、単純な符号化の逆過程にすぎず、読者は自分で検討することができる.私は文章の最後に復号アルゴリズムを与えます.
四、アルゴリズム実現
実はアルゴリズムを詳しく解くときは基本的にはっきり言っています.プログラム上では,制約判断を除いて,次のようなステップに分けられる.
右に2桁移動して、清0......このように押します.ANDで1バイト目の後2ビットと2バイト目の前4ビットをとり、シフトを新しい変数に入れ、右に2ビット移動し、高2ビットで0をクリアし、ANDで前6ビットを取り、新しい変数に入れ、データ3バイトを読み出す
1、復号化のクラスC言語実現のアルゴリズム:
BYTE LMoveBit(int base, int MoveNum)
{
BYTE result=base;
if(MoveNum==0)return 1;
if(MoveNum==1)return MoveNum;
result=base<
2、java実現:
// s BASE64
public static String getBASE64(String s) {
if (s == null)
return null;
return (new sun.misc.BASE64Encoder()).encode(s.getBytes());
}
// BASE64 s
public static String getFromBASE64(String s) {
if (s == null)
return null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b);
} catch (Exception e) {
return null;
}
}
五、一つはsun.misc.BASE 64 Decoderが実現するピクチャの復号化と符号化 package com.test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* title: base64
* @author mihoo
*
*/
public class Base64Test {
private String imageURL = "c:/test.jpg";
public void testBase64Encoder() {
BASE64Encoder encoder = new BASE64Encoder();
try {
StringBuilder pictureBuffer = new StringBuilder();
InputStream input = new FileInputStream(new File(imageURL));
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] temp = new byte[1024];
for (int len = input.read(temp); len != -1; len = input.read(temp)) {
out.write(temp, 0, len);
pictureBuffer.append(encoder.encode(out.toByteArray()));
out.reset();
}
System.out.println(pictureBuffer.toString());
System.out.println(" !");
BASE64Decoder decoder = new BASE64Decoder();
FileOutputStream write = new FileOutputStream(new File("c:/test2.png"));
byte[] decoderBytes = decoder.decodeBuffer(pictureBuffer.toString());
write.write(decoderBytes);
System.out.println(" !");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Base64Test().testBase64Encoder();
}
}
転載先:http://blog.csdn.net/cyzero/article/details/8161600
このコードを設計するとき、設計者が一番考えていると思います.
3
質問:
1.
暗号化しますか?
2.
暗号化アルゴリズムの複雑さと効率
3.
転送の処理方法
暗号化は肯定的ですが、暗号化の目的はユーザーに非常に安全に送信させることではありません.
.この暗号化方式は主に
“
君子を防ぎ小人を防ぐ
”
.一目で見ても内容が全く見えないようにすればいい.
この目的に基づいた暗号化アルゴリズムの複雑さと効率もあまり大きくも低くはできない.前の理由と同様に、MIMEプロトコルなどのEmailを送信するためのプロトコルは、どのように安全にEmailを送受信するかではなく、どのようにEmailを送受信するかを解決します.そのためアルゴリズムの複雑さは小さく、効率が高い.そうしないと、Emailを送信するために資源を大量に占有し、道が少し歪んでしまう.
しかし、上記の2点に基づいている場合、最も簡単なシーザー法を使用すればよいのですが、なぜBase 64はシーザー法より複雑に見えるのでしょうか.これは、Emailの転送中に、履歴上の理由により、EmailはASCII文字、すなわち8ビットバイトの下位7ビットの転送しか許可されないためである.したがって、ASCII以外の文字(バイトの最上位が1)を持つEmailが「履歴の問題」のあるゲートウェイを通過すると、問題が発生する可能性があります.ゲートウェイは最高位置を0にする可能性があります!明らかに、問題はこのように発生しました!そのため、メールを正常に送るためには、この問題を考えなければなりません!だから、アルファベットの位置を変えるシーザーなどの案だけではだめだ.この点についてはRFC 2046を参照することができる.
以上のいくつかの要因に基づいてBase 64符号化が生成される.
三、Base 64アルゴリズムの詳細
Base64
コード要求
3
個
8
ビットバイト(
3*8=24
)から
4
個
6
ビットのバイト(
4*6=24
)、の後に
6
位の前に2つ補充する
0
形成する
8
ビット1バイトの形式.
具体的な変換形式は以下の図を参照してください.
文字列
張
3” 110101
01 11000101 00110011
00110101 00011100 00010100 00110011
表1
このように考えることができます:
8
ビットのバイトが一連に連なる
110101011100010100110011
そして毎回順番に選択
6
個出てからこれを
6
バイナリ数の前にもう2つ追加
0(表1の00)
で、新しいバイトになりました.あとで選ぶ
6
個来て、更に追加します
0
ああ、このように押して、
24
個のバイナリ数がすべて選択されました.
実際の結果を見てみましょう.
文字列
“
張
3”
11010101 11000101 00110011
HEX: D5 HEX: C5 HEX: 33
00110101 00011100 00010100 00110011
文字'5'文字'^'文字'^T'文字'3'
十進法53十進法34十進法20十進法
51
表
2
このように
“
張
3 ”
この文字列は
Base64
として表示
”5^\^T3”
もういいですか.の間違いだ!
Base64
符号化方式は,単に変換されたコンテンツを用いて符号化するものではない.像
’^\’
文字は制御文字であり、コンピュータでは表示されず、場合によっては使用できません.
Base64
独自のエンコーディング・テーブルがあります.
The Base 64 Alphabet(文字マッピングテーブル)
Value
Encoding
Value
Encoding
Value
Encoding
Value
Encoding
0
A
17
R
34
i
51
z
1
B
18
S
35
j
52
0
2
C
19
T
36
k
53
1
3
D
20
U
37
l
54
2
4
E
21
V
38
m
55
3
5
F
22
W
39
n
56
4
6
C
23
X
40
o
57
5
7
H
24
Y
41
p
58
6
8
I
25
Z
42
q
59
7
9
J
26
a
43
r
60
8
10
K
27
b
44
s
61
9
11
L
28
c
45
t
62
+
12
M
29
d
46
u
63
/
13
N
30
e
47
v
(pad)
=
14
O
31
f
48
w
15
P
32
g
49
x
16
Q
33
h
50
y
表3
これもBase 64名の由来であり、Base 64符号化の結果、アルゴリズムによって符号化が上位2桁が0で下位6になることを代表データとするのではなく、上の表のように「A」が7桁、「a」が6桁になる.表では,符号化された番号は,得られた新しいバイトの10進数値に対応する.従って、テーブル2から対応するBase 64符号化が得られる.
文字列
“
張
3”
11010101 11000101 00110011
HEX:D5 HEX:C5 HEX:33
00110101 00011100 00010100 00110011
文字
’5’
文字
’^\’
文字
’^T’
文字
’3’
じっしん
53
じっしん
34
じっしん
20
じっしん
51
文字
’1’
文字
’i’
文字
’U’
文字
’z’
表
4
このように、文字列
“
張
3”
エンコードされて文字列になります
“1iUz”
しました.
Base64
将
3
バイトから
4
このため、符号化後の符号量(バイト単位、以下同)は符号化前の符号量よりも約多くなる
1/3
.なぜかというと
“
約
”
あ、コード量がちょうど
3
の整数倍になると、自然と多くなります.
1/3
.でもそうじゃなかったら?
注意深い人はもう気づいたかもしれませんが、
TheBase64 Alphabet
の最後に
(pad)=
文字.この文字の目的はこの問題を処理することです.
コード量が
3
の整数倍の場合、コード量
/3
の余りはもちろん
2
または
1
.変換するとき、結果が足りない
6
ビットの使用
0
該当する位置を補い、その後
6
位の前に2つ補充する
0
.空振りした結果を変換して使います
“=”
補位に来る.例えば結果が最後に残ったら
2
バイト
“
張
”
:
文字列
“
張
”
11010101 11000101
HEX:D5 HEX:C5
00110101 00011100 00010100
じっしん
53
じっしん
34
じっしん
20 pad
文字
’1’
文字
’i’
文字
’U’
文字
’=’
表
6
こうして、最後の
2
バイトが整理されて
“1iU=”
.
同様に、元のコードが1バイトしか残っていない場合は、2つ追加されます.
“=”
.この2つのケースしかないので、
Base64
のエンコーディングは、エンコーディングの最後に2つまであります.
“=” .
将に至っては
Base64
の復号化は、単純な符号化の逆過程にすぎず、読者は自分で検討することができる.私は文章の最後に復号アルゴリズムを与えます.
四、アルゴリズム実現
実はアルゴリズムを詳しく解くときは基本的にはっきり言っています.プログラム上では,制約判断を除いて,次のようなステップに分けられる.
右に2桁移動して、清0......このように押します.ANDで1バイト目の後2ビットと2バイト目の前4ビットをとり、シフトを新しい変数に入れ、右に2ビット移動し、高2ビットで0をクリアし、ANDで前6ビットを取り、新しい変数に入れ、データ3バイトを読み出す
1、復号化のクラスC言語実現のアルゴリズム:
BYTE LMoveBit(int base, int MoveNum)
{
BYTE result=base;
if(MoveNum==0)return 1;
if(MoveNum==1)return MoveNum;
result=base<
2、java実現:
// s BASE64
public static String getBASE64(String s) {
if (s == null)
return null;
return (new sun.misc.BASE64Encoder()).encode(s.getBytes());
}
// BASE64 s
public static String getFromBASE64(String s) {
if (s == null)
return null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b);
} catch (Exception e) {
return null;
}
}
五、一つはsun.misc.BASE 64 Decoderが実現するピクチャの復号化と符号化 package com.test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* title: base64
* @author mihoo
*
*/
public class Base64Test {
private String imageURL = "c:/test.jpg";
public void testBase64Encoder() {
BASE64Encoder encoder = new BASE64Encoder();
try {
StringBuilder pictureBuffer = new StringBuilder();
InputStream input = new FileInputStream(new File(imageURL));
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] temp = new byte[1024];
for (int len = input.read(temp); len != -1; len = input.read(temp)) {
out.write(temp, 0, len);
pictureBuffer.append(encoder.encode(out.toByteArray()));
out.reset();
}
System.out.println(pictureBuffer.toString());
System.out.println(" !");
BASE64Decoder decoder = new BASE64Decoder();
FileOutputStream write = new FileOutputStream(new File("c:/test2.png"));
byte[] decoderBytes = decoder.decodeBuffer(pictureBuffer.toString());
write.write(decoderBytes);
System.out.println(" !");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Base64Test().testBase64Encoder();
}
}
転載先:http://blog.csdn.net/cyzero/article/details/8161600
実はアルゴリズムを詳しく解くときは基本的にはっきり言っています.プログラム上では,制約判断を除いて,次のようなステップに分けられる.
右に2桁移動して、清0......このように押します.ANDで1バイト目の後2ビットと2バイト目の前4ビットをとり、シフトを新しい変数に入れ、右に2ビット移動し、高2ビットで0をクリアし、ANDで前6ビットを取り、新しい変数に入れ、データ3バイトを読み出す
1、復号化のクラスC言語実現のアルゴリズム:
BYTE LMoveBit(int base, int MoveNum)
{
BYTE result=base;
if(MoveNum==0)return 1;
if(MoveNum==1)return MoveNum;
result=base<
2、java実現:
// s BASE64
public static String getBASE64(String s) {
if (s == null)
return null;
return (new sun.misc.BASE64Encoder()).encode(s.getBytes());
}
// BASE64 s
public static String getFromBASE64(String s) {
if (s == null)
return null;
BASE64Decoder decoder = new BASE64Decoder();
try {
byte[] b = decoder.decodeBuffer(s);
return new String(b);
} catch (Exception e) {
return null;
}
}
五、一つはsun.misc.BASE 64 Decoderが実現するピクチャの復号化と符号化 package com.test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* title: base64
* @author mihoo
*
*/
public class Base64Test {
private String imageURL = "c:/test.jpg";
public void testBase64Encoder() {
BASE64Encoder encoder = new BASE64Encoder();
try {
StringBuilder pictureBuffer = new StringBuilder();
InputStream input = new FileInputStream(new File(imageURL));
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] temp = new byte[1024];
for (int len = input.read(temp); len != -1; len = input.read(temp)) {
out.write(temp, 0, len);
pictureBuffer.append(encoder.encode(out.toByteArray()));
out.reset();
}
System.out.println(pictureBuffer.toString());
System.out.println(" !");
BASE64Decoder decoder = new BASE64Decoder();
FileOutputStream write = new FileOutputStream(new File("c:/test2.png"));
byte[] decoderBytes = decoder.decodeBuffer(pictureBuffer.toString());
write.write(decoderBytes);
System.out.println(" !");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Base64Test().testBase64Encoder();
}
}
転載先:http://blog.csdn.net/cyzero/article/details/8161600
package com.test;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
/**
* title: base64
* @author mihoo
*
*/
public class Base64Test {
private String imageURL = "c:/test.jpg";
public void testBase64Encoder() {
BASE64Encoder encoder = new BASE64Encoder();
try {
StringBuilder pictureBuffer = new StringBuilder();
InputStream input = new FileInputStream(new File(imageURL));
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] temp = new byte[1024];
for (int len = input.read(temp); len != -1; len = input.read(temp)) {
out.write(temp, 0, len);
pictureBuffer.append(encoder.encode(out.toByteArray()));
out.reset();
}
System.out.println(pictureBuffer.toString());
System.out.println(" !");
BASE64Decoder decoder = new BASE64Decoder();
FileOutputStream write = new FileOutputStream(new File("c:/test2.png"));
byte[] decoderBytes = decoder.decodeBuffer(pictureBuffer.toString());
write.write(decoderBytes);
System.out.println(" !");
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Base64Test().testBase64Encoder();
}
}