MIME (BASE64) 专题

MIME (BASE64) 专题

什么是Base64

按照RFC2045的定义,Base64被定义为:Base64内容传送编码被设计用来把任意序列的8位字节描述为一种不易被人直接识别的形式。

为什么要使用Base64

在设计这个编码的时候,我想设计人员最主要考虑了3个问题:

  1. 是否加密?
  2. 加密算法复杂程度和效率?
  3. 如何处理传输?

加密是肯定的,但是加密的目的不是让用户发送非常安全的Email。这种加密方式主要就是“防君子不防小人”。即达到一眼望去完全看不出内容即可。 基于这个目的加密算法的复杂程度和效率也就不能太大和太低。和上一个理由类似,MIME协议等用于发送Email的协议解决的是如何收发Email,而并不是如何安全的收发Email。因此算法的复杂程度要小,效率要高,否则因为发送Email而大量占用资源,路就有点走歪了。

但是,如果是基于以上两点,那么我们使用最简单的恺撒法即可,为什么Base64看起来要比恺撒法复杂呢?这是因为在Email的传送过程中,由于历史原因,Email只被允许传送ASCII字符,即一个8位字节的低7位。因此,如果您发送了一封带有非ASCII字符(即字节的最高位是1)的Email通过有“历史问题”的网关时就可能会出现问题。网关可能会把最高位置为0!很明显,问题就这样产生了!因此,为了能够正常的传送Email,这个问题就必须考虑!所以,单单靠改变字母的位置的恺撒之类的方案也就不行了。关于这一点可以参考 RFC2046。 基于以上的一些主要原因产生了Base64编码。

参考邮件正文 Content-Transfer-Encoding: base64

OpenSSL - Base64

2.1.1. Linux Command base64

$ cat file | base64

2.1.2. PHP Base64

2.1.2.1. base64_encode

base64_encode

(PHP 3, PHP 4, PHP 5)

base64_encode -- 使用 MIME base64 对数据进行编码

说明

string base64_encode ( string data )

base64_encode() returns 使用 base64 对 data 进行编码。设计此种编码是为了使二进制数据可以通过非纯 8-bit 的传输层传输,例如电子邮件的主体。

Base64-encoded 数据要比原始数据多占用 33% 左右的空间。

例子 1. base64_encode() 示例

<?php
 $str = 'This is an encoded string';
 echo base64_encode($str);
?>

此示例将显示:

VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==

例子 2. stream_filter_append() 示例

<?php
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'convert.base64-encode');
fwrite($fp, "This is a test.\n");
fclose($fp);
/* Outputs: VGhpcyBpcyBhIHRlc3QuCg== */
echo "\n============================================\n";

$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'convert.base64-decode');
fwrite($fp, "VGhpcyBpcyBhIHRlc3QuCg==");
fclose($fp);
/* Outputs: This is a test. */
echo "============================================\n";

$param = array('line-length' => 8, 'line-break-chars' => "\r\n");
$fp = fopen('php://output', 'w');
stream_filter_append($fp, 'convert.base64-encode', STREAM_FILTER_WRITE, $param);
fwrite($fp, "This is a test.\n");
fclose($fp);
/* Outputs: VGhpcyBp
 : cyBhIHRl
 : c3QuCg== */
?>

2.1.2.2. base64_decode

base64_decode

(PHP 3, PHP 4, PHP 5)

base64_decode -- 对使用 MIME base64 编码的数据进行解码

说明

string base64_decode ( string encoded_data )

base64_decode() 对 encoded_data 进行解码,返回原始数据,失败则返回 FALSE。返回的数据可能是二进制的。

例子 1. base64_decode() 示例

<?php
$str = 'VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==';
echo base64_decode($str);
?>
 

此示例将显示:

This is an encoded string

2.1.3. Python Base64

编码:b64encode

import base64
base64.b64encode('This is an encoded string')

此示例将显示:

'VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw=='

解码:

import base64
base64.b64decode('VGhpcyBpcyBhbiBlbmNvZGVkIHN0cmluZw==')

此示例将显示:

This is an encoded string

2.1.4. perl base64

perl -MMIME::Base64 -e 'print encode_base64("netkiller");'

perl -MMIME::Base64 -e 'print decode_base64("bmV0a2lsbGVy");'

2.1.5. Java Base64

2.1.5.1. Java 7

import java.io.*;
public class base64Test {

 public static void main(String[] args) {

  try {
  String text = "This is an encoded string";
  //Convert a string to base64 string
  byte[] buf = text.getBytes();
  String encode = new sun.misc.BASE64Encoder().encode(buf);
  System.out.println(encode);

  // Convert base64 string to a string
  buf = new sun.misc.BASE64Decoder().decodeBuffer(encode);
  String decode = new String(buf);
  System.out.println(decode);
  } catch (IOException e) {

  }
 }
}
 

2.1.5.2. Java 8

package cn.netkiller.test;

import java.nio.charset.StandardCharsets;
import java.util.Base64;

public class Base64Test {
 public static void main(String[] args) {
 final String text = "http://www.netkiller.cn/index.html";

 final String encoded = Base64.getEncoder().encodeToString(text.getBytes(StandardCharsets.UTF_8));
 System.out.println(encoded);

 final String decoded = new String(Base64.getDecoder().decode(encoded), StandardCharsets.UTF_8);
 System.out.println(decoded);
 }
}
package cn.netkiller.security;

import java.io.UnsupportedEncodingException;
import java.util.Base64;

public class Base64Test {

 public Base64Test() {
 // TODO Auto-generated constructor stub
 }

 public static void main(String[] args) throws UnsupportedEncodingException {
 // TODO Auto-generated method stub
 String asB64 = Base64.getEncoder().encodeToString("some string".getBytes("utf-8"));
 System.out.println(asB64); // 输出为: c29tZSBzdHJpbmc=

 // 解码
 byte[] asBytes = Base64.getDecoder().decode("c29tZSBzdHJpbmc=");
 System.out.println(new String(asBytes, "utf-8")); // 输出为: some string

 // 但由于URL对反斜线“/”有特殊的意义,因此URL编码需要替换掉它,使用下划线替换
 String basicEncoded = Base64.getEncoder().encodeToString("subjects?abcd".getBytes("utf-8"));
 System.out.println("Using Basic Alphabet: " + basicEncoded);

 String urlEncoded = Base64.getUrlEncoder().encodeToString("subjects?abcd".getBytes("utf-8"));
 System.out.println("Using URL Alphabet: " + urlEncoded);
 }

}
  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

netkiller-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值