Java 和 PHP 中的 Base64

Base64 in Java and PHP

以下Java代码:

String ss = Base64.encodeBase64URLSafeString(xmlRequest.getBytes());
System.out.println(ss);

产生:

PHJlcXVlc3Q-PG1lcmNoYW50X2lkPjQ2PC9tZXJjaGFudF9pZD48b3JkZXJfaWQ-MzM8L29yZGVyX2lkPjxhbW91bnQ-MzwvYW1vdW50PjxkZXNjcmlwdGlvbj5oZWhlPC9kZXNjcmlwdGlvbj48L3JlcXVlc3Q-

虽然此 PHP 代码:

$xml='<request><merchant_id>46</merchant_id><order_id>33</order_id><amount>3</amount><description>hehe</description></request>';
$xml_encoded = base64_encode($xml);

产生: PHJlcXVlc3Q+PG1lcmNoYW50X2lkPjQ2PC9tZXJjaGFudF9pZD48b3JkZXJfaWQ+MzM8L29yZGVyX2lkPjxhbW91bnQ+MzwvYW1vdW50PjxkZXNjcmlwdGlvbj5oZWhlPC9kZXNjcmlwdGlvbj48L3JlcXVlc3Q+

其中一个有 - 个字符,而另一个有 + 个。差异从何而来?

查看this article for some of the variants in use. Looks like - is used when the representation needs to be safe for including in an URL e.g. as a query argument. See also the Base64源代码:

/**
 * This array is a lookup table that translates 6-bit positive integer index values into their "Base64 Alphabet"
 * equivalents as specified in Table 1 of RFC 2045.
 *
 * Thanks to "commons" project in ws.apache.org for this code.
 * http://svn.apache.org/repos/asf/webservices/commons/trunk/modules/util/
 */
private static final byte[] STANDARD_ENCODE_TABLE = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
        'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
        'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
};

/**
 * This is a copy of the STANDARD_ENCODE_TABLE above, but with + and /
 * changed to - and _ to make the encoded Base64 results more URL-SAFE.
 * This table is only used when the Base64's mode is set to URL-SAFE.
 */
private static final byte[] URL_SAFE_ENCODE_TABLE = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
        'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
        'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '-', '_'
};

这是因为Base64.encodeBase64URLSafeString()使用的"URL-Safe Base64 Variant"将+/替换为-_:

Encodes binary data using a URL-safe variation of the base64 algorithm but does not chunk the output. The url-safe variation emits - and _ instead of + and / characters. Note: no padding is added.

您只需将 +/ 更改为 -_.

即可简单地翻译这两种格式

要获得与 PHP 相同的输出,只需使用 Base64.encodeBase64String()

Base 64 是字符 a-zA-Z0-9 以及最后两个字符 +/

为了使编码 URL 安全,我们不能使用 / 所以最后两个字符被 URL 安全变体 _-.

如果您使用:

final Base64.Encoder encoder = Base64.getEncoder();
encoder.encodeToString(...)

您将获得与 PHP 示例相同的输出。

P.S。这是 JDK 中内置的新 java.util.Base64 class - 无需使用奥术通用库。