提交 92bd7522 编写于 作者: S sherman

8004088: hg push for bug#4235519 failed to push all files

Summary: pushed all base64 files
Reviewed-by: alanb, mduigou
上级 137e212c
此差异已折叠。
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/**
* @test 4235519
* @summary tests java.util.Base64
*/
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Base64;
import java.util.Random;
public class TestBase64 {
public static void main(String args[]) throws Throwable {
int numRuns = 10;
int numBytes = 200;
if (args.length > 1) {
numRuns = Integer.parseInt(args[0]);
numBytes = Integer.parseInt(args[1]);
}
test(Base64.getEncoder(), Base64.getDecoder(),
numRuns, numBytes);
test(Base64.getUrlEncoder(), Base64.getUrlDecoder(),
numRuns, numBytes);
test(Base64.getMimeEncoder(), Base64.getMimeDecoder(),
numRuns, numBytes);
Random rnd = new java.util.Random();
byte[] nl_1 = new byte[] {'\n'};
byte[] nl_2 = new byte[] {'\n', '\r'};
byte[] nl_3 = new byte[] {'\n', '\r', '\n'};
for (int i = 0; i < 10; i++) {
int len = rnd.nextInt(200) + 4;
test(Base64.getEncoder(len, nl_1),
Base64.getMimeDecoder(),
numRuns, numBytes);
test(Base64.getEncoder(len, nl_2),
Base64.getMimeDecoder(),
numRuns, numBytes);
test(Base64.getEncoder(len, nl_3),
Base64.getMimeDecoder(),
numRuns, numBytes);
}
testNull(Base64.getEncoder());
testNull(Base64.getUrlEncoder());
testNull(Base64.getMimeEncoder());
testNull(Base64.getEncoder(10, new byte[]{'\n'}));
testNull(Base64.getDecoder());
testNull(Base64.getUrlDecoder());
testNull(Base64.getMimeDecoder());
checkNull(new Runnable() { public void run() { Base64.getEncoder(10, null); }});
testIOE(Base64.getEncoder());
testIOE(Base64.getUrlEncoder());
testIOE(Base64.getMimeEncoder());
testIOE(Base64.getEncoder(10, new byte[]{'\n'}));
byte[] src = new byte[1024];
new Random().nextBytes(src);
final byte[] decoded = Base64.getEncoder().encode(src);
testIOE(Base64.getDecoder(), decoded);
testIOE(Base64.getMimeDecoder(), decoded);
testIOE(Base64.getUrlDecoder(), Base64.getUrlEncoder().encode(src));
// illegal line separator
checkIAE(new Runnable() { public void run() { Base64.getEncoder(10, new byte[]{'\r', 'N'}); }});
// illegal base64 character
decoded[2] = (byte)0xe0;
checkIAE(new Runnable() {
public void run() { Base64.getDecoder().decode(decoded); }});
checkIAE(new Runnable() {
public void run() { Base64.getDecoder().decode(decoded, new byte[1024]); }});
checkIAE(new Runnable() { public void run() {
Base64.getDecoder().decode(ByteBuffer.wrap(decoded)); }});
checkIAE(new Runnable() { public void run() {
Base64.getDecoder().decode(ByteBuffer.wrap(decoded), ByteBuffer.allocate(1024)); }});
checkIAE(new Runnable() { public void run() {
Base64.getDecoder().decode(ByteBuffer.wrap(decoded), ByteBuffer.allocateDirect(1024)); }});
}
private static sun.misc.BASE64Encoder sunmisc = new sun.misc.BASE64Encoder();
private static void test(Base64.Encoder enc, Base64.Decoder dec,
int numRuns, int numBytes) throws Throwable {
Random rnd = new java.util.Random();
enc.encode(new byte[0]);
dec.decode(new byte[0]);
for (int i=0; i<numRuns; i++) {
for (int j=1; j<numBytes; j++) {
byte[] orig = new byte[j];
rnd.nextBytes(orig);
// --------testing encode/decode(byte[])--------
byte[] encoded = enc.encode(orig);
byte[] decoded = dec.decode(encoded);
checkEqual(orig, decoded,
"Base64 array encoding/decoding failed!");
// compare to sun.misc.BASE64Encoder
byte[] encoded2 = sunmisc.encode(orig).getBytes("ASCII");
checkEqual(normalize(encoded),
normalize(encoded2),
"Base64 enc.encode() does not match sun.misc.base64!");
// remove padding '=' to test non-padding decoding case
if (encoded[encoded.length -2] == '=')
encoded2 = Arrays.copyOf(encoded, encoded.length -2);
else if (encoded[encoded.length -1] == '=')
encoded2 = Arrays.copyOf(encoded, encoded.length -1);
else
encoded2 = null;
// --------testing encodetoString(byte[])/decode(String)--------
String str = enc.encodeToString(orig);
if (!Arrays.equals(str.getBytes("ASCII"), encoded)) {
throw new RuntimeException(
"Base64 encodingToString() failed!");
}
byte[] buf = dec.decode(new String(encoded, "ASCII"));
checkEqual(buf, orig, "Base64 decoding(String) failed!");
if (encoded2 != null) {
buf = dec.decode(new String(encoded2, "ASCII"));
checkEqual(buf, orig, "Base64 decoding(String) failed!");
}
//-------- testing encode/decode(Buffer)--------
testEncode(enc, ByteBuffer.wrap(orig), encoded);
ByteBuffer bin = ByteBuffer.allocateDirect(orig.length);
bin.put(orig).flip();
testEncode(enc, bin, encoded);
testDecode(dec, ByteBuffer.wrap(encoded), orig);
bin = ByteBuffer.allocateDirect(encoded.length);
bin.put(encoded).flip();
testDecode(dec, bin, orig);
if (encoded2 != null)
testDecode(dec, ByteBuffer.wrap(encoded2), orig);
// -------- testing encode(Buffer, Buffer)--------
testEncode(enc, encoded,
ByteBuffer.wrap(orig),
ByteBuffer.allocate(encoded.length + 10));
testEncode(enc, encoded,
ByteBuffer.wrap(orig),
ByteBuffer.allocateDirect(encoded.length + 10));
// --------testing decode(Buffer, Buffer);--------
testDecode(dec, orig,
ByteBuffer.wrap(encoded),
ByteBuffer.allocate(orig.length + 10));
testDecode(dec, orig,
ByteBuffer.wrap(encoded),
ByteBuffer.allocateDirect(orig.length + 10));
// --------testing decode.wrap(input stream)--------
// 1) random buf length
ByteArrayInputStream bais = new ByteArrayInputStream(encoded);
InputStream is = dec.wrap(bais);
buf = new byte[orig.length + 10];
int len = orig.length;
int off = 0;
while (true) {
int n = rnd.nextInt(len);
if (n == 0)
n = 1;
n = is.read(buf, off, n);
if (n == -1) {
checkEqual(off, orig.length,
"Base64 stream decoding failed");
break;
}
off += n;
len -= n;
if (len == 0)
break;
}
buf = Arrays.copyOf(buf, off);
checkEqual(buf, orig, "Base64 stream decoding failed!");
// 2) read one byte each
bais.reset();
is = dec.wrap(bais);
buf = new byte[orig.length + 10];
off = 0;
int b;
while ((b = is.read()) != -1) {
buf[off++] = (byte)b;
}
buf = Arrays.copyOf(buf, off);
checkEqual(buf, orig, "Base64 stream decoding failed!");
// --------testing encode.wrap(output stream)--------
ByteArrayOutputStream baos = new ByteArrayOutputStream((orig.length + 2) / 3 * 4 + 10);
OutputStream os = enc.wrap(baos);
off = 0;
len = orig.length;
for (int k = 0; k < 5; k++) {
if (len == 0)
break;
int n = rnd.nextInt(len);
if (n == 0)
n = 1;
os.write(orig, off, n);
off += n;
len -= n;
}
if (len != 0)
os.write(orig, off, len);
os.close();
buf = baos.toByteArray();
checkEqual(buf, encoded, "Base64 stream encoding failed!");
// 2) write one byte each
baos.reset();
os = enc.wrap(baos);
off = 0;
while (off < orig.length) {
os.write(orig[off++]);
}
os.close();
buf = baos.toByteArray();
checkEqual(buf, encoded, "Base64 stream encoding failed!");
// --------testing encode(in, out); -> bigger buf--------
buf = new byte[encoded.length + rnd.nextInt(100)];
int ret = enc.encode(orig, buf);
checkEqual(ret, encoded.length,
"Base64 enc.encode(src, null) returns wrong size!");
buf = Arrays.copyOf(buf, ret);
checkEqual(buf, encoded,
"Base64 enc.encode(src, dst) failed!");
// --------testing decode(in, out); -> bigger buf--------
buf = new byte[orig.length + rnd.nextInt(100)];
ret = dec.decode(encoded, buf);
checkEqual(ret, orig.length,
"Base64 enc.encode(src, null) returns wrong size!");
buf = Arrays.copyOf(buf, ret);
checkEqual(buf, orig,
"Base64 dec.decode(src, dst) failed!");
}
}
}
private static final byte[] ba_null = null;
private static final String str_null = null;
private static final ByteBuffer bb_null = null;
private static void testNull(final Base64.Encoder enc) {
checkNull(new Runnable() { public void run() { enc.encode(ba_null); }});
checkNull(new Runnable() { public void run() { enc.encodeToString(ba_null); }});
checkNull(new Runnable() { public void run() { enc.encode(ba_null, new byte[10]); }});
checkNull(new Runnable() { public void run() { enc.encode(new byte[10], ba_null); }});
checkNull(new Runnable() { public void run() { enc.encode(bb_null); }});
checkNull(new Runnable() { public void run() { enc.encode(bb_null, ByteBuffer.allocate(10), 0); }});
checkNull(new Runnable() { public void run() { enc.encode(ByteBuffer.allocate(10), bb_null, 0); }});
}
private static void testNull(final Base64.Decoder dec) {
checkNull(new Runnable() { public void run() { dec.decode(ba_null); }});
checkNull(new Runnable() { public void run() { dec.decode(str_null); }});
checkNull(new Runnable() { public void run() { dec.decode(ba_null, new byte[10]); }});
checkNull(new Runnable() { public void run() { dec.decode(new byte[10], ba_null); }});
checkNull(new Runnable() { public void run() { dec.decode(bb_null); }});
checkNull(new Runnable() { public void run() { dec.decode(bb_null, ByteBuffer.allocate(10)); }});
checkNull(new Runnable() { public void run() { dec.decode(ByteBuffer.allocate(10), bb_null); }});
}
private static interface Testable {
public void test() throws Throwable;
}
private static void testIOE(final Base64.Encoder enc) throws Throwable {
ByteArrayOutputStream baos = new ByteArrayOutputStream(8192);
final OutputStream os = enc.wrap(baos);
os.write(new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9});
os.close();
checkIOE(new Testable() { public void test() throws Throwable { os.write(10); }});
checkIOE(new Testable() { public void test() throws Throwable { os.write(new byte[] {10}); }});
checkIOE(new Testable() { public void test() throws Throwable { os.write(new byte[] {10}, 1, 4); }});
}
private static void testIOE(final Base64.Decoder dec, byte[] decoded) throws Throwable {
ByteArrayInputStream bais = new ByteArrayInputStream(decoded);
final InputStream is = dec.wrap(bais);
is.read(new byte[10]);
is.close();
checkIOE(new Testable() { public void test() throws Throwable { is.read(); }});
checkIOE(new Testable() { public void test() throws Throwable { is.read(new byte[] {10}); }});
checkIOE(new Testable() { public void test() throws Throwable { is.read(new byte[] {10}, 1, 4); }});
checkIOE(new Testable() { public void test() throws Throwable { is.available(); }});
checkIOE(new Testable() { public void test() throws Throwable { is.skip(20); }});
}
private static final void checkNull(Runnable r) {
try {
r.run();
throw new RuntimeException("NPE is not thrown as expected");
} catch (NullPointerException npe) {}
}
private static final void checkIOE(Testable t) throws Throwable {
try {
t.test();
throw new RuntimeException("IOE is not thrown as expected");
} catch (IOException ioe) {}
}
private static final void checkIAE(Runnable r) throws Throwable {
try {
r.run();
throw new RuntimeException("IAE is not thrown as expected");
} catch (IllegalArgumentException iae) {}
}
private static final void testEncode(Base64.Encoder enc, ByteBuffer bin, byte[] expected)
throws Throwable {
ByteBuffer bout = enc.encode(bin);
byte[] buf = new byte[bout.remaining()];
bout.get(buf);
if (bin.hasRemaining()) {
throw new RuntimeException(
"Base64 enc.encode(ByteBuffer) failed!");
}
checkEqual(buf, expected, "Base64 enc.encode(bf, bf) failed!");
}
private static final void testDecode(Base64.Decoder dec, ByteBuffer bin, byte[] expected)
throws Throwable {
ByteBuffer bout = dec.decode(bin);
byte[] buf = new byte[bout.remaining()];
bout.get(buf);
checkEqual(buf, expected, "Base64 dec.decode(bf) failed!");
}
private static final void testEncode(Base64.Encoder enc, byte[] expected,
ByteBuffer ibb, ByteBuffer obb)
throws Throwable {
Random rnd = new Random();
int bytesOut = enc.encode(ibb, obb, 0);
if (ibb.hasRemaining()) {
throw new RuntimeException(
"Base64 enc.encode(bf, bf) failed with wrong return!");
}
obb.flip();
byte[] buf = new byte[obb.remaining()];
obb.get(buf);
checkEqual(buf, expected, "Base64 enc.encode(bf, bf) failed!");
ibb.rewind();
obb.position(0);
obb.limit(0);
bytesOut = 0;
do { // increase the "limit" incrementally & randomly
int n = rnd.nextInt(expected.length - obb.position());
if (n == 0)
n = 1;
obb.limit(obb.limit() + n);
//obb.limit(Math.min(obb.limit() + n, expected.length));
bytesOut = enc.encode(ibb, obb, bytesOut);
} while (ibb.hasRemaining());
obb.flip();
buf = new byte[obb.remaining()];
obb.get(buf);
checkEqual(buf, expected, "Base64 enc.encode(bf, bf) failed!");
}
private static final void testDecode(Base64.Decoder dec, byte[] expected,
ByteBuffer ibb, ByteBuffer obb)
throws Throwable {
Random rnd = new Random();
dec.decode(ibb, obb);
if (ibb.hasRemaining()) {
throw new RuntimeException(
"Base64 dec.decode(bf, bf) failed with un-decoded ibb!");
}
obb.flip();
byte[] buf = new byte[obb.remaining()];
obb.get(buf);
checkEqual(buf, expected, "Base64 dec.decode(bf, bf) failed!");
ibb.rewind();
obb.position(0);
obb.limit(0);
do { // increase the "limit" incrementally & randomly
int n = rnd.nextInt(expected.length - obb.position());
if (n == 0)
n = 1;
obb.limit(obb.limit() + n);
dec.decode(ibb, obb);
} while (ibb.hasRemaining());
obb.flip();
buf = new byte[obb.remaining()];
obb.get(buf);
checkEqual(buf, expected, "Base64 dec.decode(bf, bf) failed!");
}
private static final void checkEqual(int v1, int v2, String msg)
throws Throwable {
if (v1 != v2) {
System.out.printf(" v1=%d%n", v1);
System.out.printf(" v2=%d%n", v2);
throw new RuntimeException(msg);
}
}
private static final void checkEqual(byte[] r1, byte[] r2, String msg)
throws Throwable {
if (!Arrays.equals(r1, r2)) {
System.out.printf(" r1[%d]=[%s]%n", r1.length, new String(r1));
System.out.printf(" r2[%d]=[%s]%n", r2.length, new String(r2));
throw new RuntimeException(msg);
}
}
// remove line feeds,
private static final byte[] normalize(byte[] src) {
int n = 0;
boolean hasUrl = false;
for (int i = 0; i < src.length; i++) {
if (src[i] == '\r' || src[i] == '\n')
n++;
if (src[i] == '-' || src[i] == '_')
hasUrl = true;
}
if (n == 0 && hasUrl == false)
return src;
byte[] ret = new byte[src.length - n];
int j = 0;
for (int i = 0; i < src.length; i++) {
if (src[i] == '-')
ret[j++] = '+';
else if (src[i] == '_')
ret[j++] = '/';
else if (src[i] != '\r' && src[i] != '\n')
ret[j++] = src[i];
}
return ret;
}
}
/*
* Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test 4235519
* @author Eric Wang <yiming.wang@oracle.com>
* @summary tests java.util.Base64
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.Base64.Encoder;
import java.util.Objects;
import java.util.Random;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;
public class TestBase64Golden {
public static void main(String[] args) throws Exception {
test0(Base64Type.BASIC, Base64.getEncoder(), Base64.getDecoder(),
"plain.txt", "baseEncode.txt");
test0(Base64Type.URLSAFE, Base64.getUrlEncoder(), Base64.getUrlDecoder(),
"plain.txt", "urlEncode.txt");
test0(Base64Type.MIME, Base64.getMimeEncoder(), Base64.getMimeDecoder(),
"plain.txt", "mimeEncode.txt");
test1();
test2();
}
public static void test0(Base64Type type, Encoder encoder, Decoder decoder,
String srcFile, String encodedFile) throws Exception {
String[] srcLns = Files.readAllLines(Paths.get(SRCDIR, srcFile), DEF_CHARSET)
.toArray(new String[0]);
String[] encodedLns = Files.readAllLines(Paths.get(SRCDIR, encodedFile),
DEF_CHARSET)
.toArray(new String[0]);
int lns = 0;
for (String srcStr : srcLns) {
String encodedStr = null;
if (type != Base64Type.MIME) {
encodedStr = encodedLns[lns++];
} else {
while (lns < encodedLns.length) {
String s = encodedLns[lns++];
if (s.length() == 0)
break;
if (encodedStr != null) {
encodedStr += DEFAULT_CRLF + s;
} else {
encodedStr = s;
}
}
if (encodedStr == null && srcStr.length() == 0) {
encodedStr = "";
}
}
System.out.printf("%n src[%d]: %s%n", srcStr.length(), srcStr);
System.out.printf("encoded[%d]: %s%n", encodedStr.length(), encodedStr);
byte[] srcArr = srcStr.getBytes(DEF_CHARSET);
byte[] encodedArr = encodedStr.getBytes(DEF_CHARSET);
ByteBuffer srcBuf = ByteBuffer.wrap(srcArr);
ByteBuffer encodedBuf = ByteBuffer.wrap(encodedArr);
byte[] resArr = new byte[encodedArr.length];
// test int encode(byte[], byte[])
int len = encoder.encode(srcArr, resArr);
assertEqual(len, encodedArr.length);
assertEqual(resArr, encodedArr);
// test byte[] encode(byte[])
resArr = encoder.encode(srcArr);
assertEqual(resArr, encodedArr);
// test ByteBuffer encode(ByteBuffer)
int limit = srcBuf.limit();
ByteBuffer resBuf = encoder.encode(srcBuf);
assertEqual(srcBuf.position(), limit);
assertEqual(srcBuf.limit(), limit);
assertEqual(resBuf, encodedBuf);
srcBuf.rewind(); // reset for next test
// test encode(ByteBuffer, ByteBuffer, bytesOut)
resBuf.clear();
len = encoder.encode(srcBuf, resBuf, 0);
assertEqual(len, encodedArr.length);
assertEqual(srcBuf.position(), limit);
assertEqual(srcBuf.limit(), limit);
assertEqual(resBuf.position(), len);
resBuf.flip();
assertEqual(resBuf, encodedBuf);
srcBuf.rewind();
// test encode(ByteBuffer, ByteBuffer, bytesOut)[direct]
ByteBuffer resBuf_d = ByteBuffer.allocateDirect(encodedArr.length);
len = encoder.encode(srcBuf, resBuf_d, 0);
assertEqual(len, encodedArr.length);
assertEqual(srcBuf.position(), limit);
assertEqual(srcBuf.limit(), limit);
assertEqual(resBuf_d.position(), len);
resBuf_d.flip();
assertEqual(resBuf_d, encodedBuf);
srcBuf.rewind();
// test String encodeToString(byte[])
String resEncodeStr = encoder.encodeToString(srcArr);
assertEqual(resEncodeStr, encodedStr);
// test int decode(byte[], byte[])
resArr = new byte[srcArr.length];
len = decoder.decode(encodedArr, resArr);
assertEqual(len, srcArr.length);
assertEqual(resArr, srcArr);
// test byte[] decode(byte[])
resArr = decoder.decode(encodedArr);
assertEqual(resArr, srcArr);
// test ByteBuffer decode(ByteBuffer)
limit = encodedBuf.limit();
resBuf = decoder.decode(encodedBuf);
assertEqual(encodedBuf.position(), limit);
assertEqual(encodedBuf.limit(), limit);
assertEqual(resBuf, srcBuf);
encodedBuf.rewind(); // reset for next test
// test int decode(ByteBuffer, ByteBuffer)
resBuf.clear();
len = decoder.decode(encodedBuf, resBuf);
assertEqual(len, srcArr.length);
assertEqual(encodedBuf.position(), limit);
assertEqual(encodedBuf.limit(), limit);
assertEqual(resBuf.position(), len);
resBuf.flip();
assertEqual(resBuf, srcBuf);
encodedBuf.rewind(); // reset for next test
// test int decode(ByteBuffer, ByteBuffer)[direct]
resBuf_d = ByteBuffer.allocateDirect(srcArr.length);
len = decoder.decode(encodedBuf, resBuf_d);
assertEqual(len, srcArr.length);
assertEqual(encodedBuf.position(), limit);
assertEqual(encodedBuf.limit(), limit);
assertEqual(resBuf_d.position(), len);
resBuf_d.flip();
assertEqual(resBuf_d, srcBuf);
encodedBuf.rewind(); // reset for next test
// test byte[] decode(String)
resArr = decoder.decode(encodedStr);
assertEqual(resArr, srcArr);
// test compatible with sun.misc.Base64Encoder
if (type == Base64Type.MIME) {
sun.misc.BASE64Encoder miscEncoder = new BASE64Encoder();
sun.misc.BASE64Decoder miscDecoder = new BASE64Decoder();
resArr = decoder.decode(miscEncoder.encode(srcArr));
assertEqual(resArr, srcArr);
resArr = encoder.encode(miscDecoder.decodeBuffer(encodedStr));
assertEqual(new String(resArr, DEF_CHARSET), encodedStr);
}
}
}
private static void test1() throws Exception {
byte[] src = new byte[6];
new Random().nextBytes(src);
ByteBuffer srcBuf = ByteBuffer.allocate(10);
srcBuf.position(2);
srcBuf.mark();
srcBuf.limit(8);
srcBuf.put(src);
srcBuf.reset();
ByteBuffer dstBuf = ByteBuffer.allocate((src.length + 2) / 3 * 4);
Base64.getEncoder().encode(srcBuf, dstBuf, 0);
dstBuf.rewind();
byte[] dst = new byte[dstBuf.limit()];
dstBuf.get(dst);
System.out.printf("%n src[%d]: %s%n", src.length, new String(src));
System.out.printf("encoded[%d]: %s%n", dst.length, new String(dst));
assertEqual(src, Base64.getDecoder().decode(dst));
dstBuf = ByteBuffer.allocateDirect((src.length + 2) / 3 * 4);
srcBuf.reset();
Base64.getEncoder().encode(srcBuf, dstBuf, 0);
dstBuf.rewind();
dst = new byte[dstBuf.limit()];
dstBuf.get(dst);
assertEqual(src, Base64.getDecoder().decode(dst));
}
private static void test2() throws Exception {
byte[] src = new byte[] {
46, -97, -35, -44, 127, -60, -39, -4, -112, 34, -57, 47, -14, 67,
40, 18, 90, -59, 68, 112, 23, 121, -91, 94, 35, 49, 104, 17, 30,
-80, -104, -3, -53, 27, 38, -72, -47, 113, -52, 18, 5, -126 };
Encoder encoder = Base64.getEncoder(49, new byte[] { 0x7e });
byte[] encoded = encoder.encode(src);
Decoder decoder = Base64.getMimeDecoder();
byte[] decoded = decoder.decode(encoded);
if (!Objects.deepEquals(src, decoded)) {
throw new RuntimeException();
}
}
// helper
enum Base64Type {
BASIC, URLSAFE, MIME
}
private static final String SRCDIR = System.getProperty("test.src", ".");
private static final Charset DEF_CHARSET = StandardCharsets.US_ASCII;
private static final String DEF_EXCEPTION_MSG =
"Assertion failed! The result is not same as expected";
private static final String DEFAULT_CRLF = "\r\n";
private static void assertEqual(Object result, Object expect) {
if (!Objects.deepEquals(result, expect)) {
String resultStr = result.toString();
String expectStr = expect.toString();
if (result instanceof byte[]) {
resultStr = new String((byte[]) result, DEF_CHARSET);
}
if (expect instanceof byte[]) {
expectStr = new String((byte[]) expect, DEF_CHARSET);
}
throw new RuntimeException(DEF_EXCEPTION_MSG +
" result: " + resultStr + " expected: " + expectStr);
}
}
}
VGhpcyB0ZXN0IGRhdGEgaXMgcGFydCBvZiByZmMyMDQ1IHdoaWNoIGluY2x1ZGVzIGFsbCBjaGFyYWN0ZXJzIGF+eiBBflosIDB+OSBhbmQgYWxsIHN5bWJvbHMs
SXQgaXMgdXNlZCB0byB0ZXN0IGphdmEudXRpbC5CYXNlNjQuRW5jb2RlciwgYW5kIHdpbGwgYmUgZW5jb2RlZCBieSBvcmcuYXBhY2hlLmNvbW1vbnMuY29kZWMuYmluYXJ5LkJhc2U2NC5qYXZh
dG8gdGVzdCBqYXZhLnV0aWwuQmFzZTY0LkRlY29kZXI7
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgIFtQYWdlIDFd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
ICAgVGhlc2UgZG9jdW1lbnRzIGFyZSByZXZpc2lvbnMgb2YgUkZDcyAxNTIxLCAxNTIyLCBhbmQgMTU5MCwgd2hpY2g=
ICAgdGhlbXNlbHZlcyB3ZXJlIHJldmlzaW9ucyBvZiBSRkNzIDEzNDEgYW5kIDEzNDIuICBBbiBhcHBlbmRpeCBpbiBSRkM=
ICAgMjA0OSBkZXNjcmliZXMgZGlmZmVyZW5jZXMgYW5kIGNoYW5nZXMgZnJvbSBwcmV2aW91cyB2ZXJzaW9ucy4=
VGFibGUgb2YgQ29udGVudHM=
ICAgMS4gSW50cm9kdWN0aW9uIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgIDM=
ICAgMi4gRGVmaW5pdGlvbnMsIENvbnZlbnRpb25zLCBhbmQgR2VuZXJpYyBCTkYgR3JhbW1hciAuLi4uICAgIDU=
ICAgMy4gTUlNRSBIZWFkZXIgRmllbGRzIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgIDg=
ICAgNC4gTUlNRS1WZXJzaW9uIEhlYWRlciBGaWVsZCAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgIDg=
ICAgNS4gQ29udGVudC1UeXBlIEhlYWRlciBGaWVsZCAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMTA=
ICAgNi4gQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uICAgMTQ=
ICAgNy4gQ29udGVudC1JRCBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjY=
ICAgOC4gQ29udGVudC1EZXNjcmlwdGlvbiBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgOS4gQWRkaXRpb25hbCBNSU1FIEhlYWRlciBGaWVsZHMgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgMTAuIFN1bW1hcnkgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgMTEuIFNlY3VyaXR5IENvbnNpZGVyYXRpb25zIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgMTIuIEF1dGhvcnMnIEFkZHJlc3NlcyAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjg=
ICAgQS4gQ29sbGVjdGVkIEdyYW1tYXIgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjk=
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgIFtQYWdlIDdd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
My4gIE1JTUUgSGVhZGVyIEZpZWxkcw==
ICAgTUlNRSBkZWZpbmVzIGEgbnVtYmVyIG9mIG5ldyBSRkMgODIyIGhlYWRlciBmaWVsZHMgdGhhdCBhcmUgdXNlZCB0bw==
ICAgZGVzY3JpYmUgdGhlIGNvbnRlbnQgb2YgYSBNSU1FIGVudGl0eS4gIFRoZXNlIGhlYWRlciBmaWVsZHMgb2NjdXIgaW4=
ICAgYXQgbGVhc3QgdHdvIGNvbnRleHRzOg==
ICAgICgxKSAgIEFzIHBhcnQgb2YgYSByZWd1bGFyIFJGQyA4MjIgbWVzc2FnZSBoZWFkZXIu
ICAgICgyKSAgIEluIGEgTUlNRSBib2R5IHBhcnQgaGVhZGVyIHdpdGhpbiBhIG11bHRpcGFydA==
ICAgICAgICAgIGNvbnN0cnVjdC4=
ICAgVGhlIGZvcm1hbCBkZWZpbml0aW9uIG9mIHRoZXNlIGhlYWRlciBmaWVsZHMgaXMgYXMgZm9sbG93czo=
ICAgICBNSU1FLW1lc3NhZ2UtaGVhZGVycyA6PSBlbnRpdHktaGVhZGVycw==
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHM=
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uIENSTEY=
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IFRoZSBvcmRlcmluZyBvZiB0aGUgaGVhZGVy
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IGZpZWxkcyBpbXBsaWVkIGJ5IHRoaXMgQk5G
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IGRlZmluaXRpb24gc2hvdWxkIGJlIGlnbm9yZWQu
ICAgICBNSU1FLXBhcnQtaGVhZGVycyA6PSBlbnRpdHktaGVhZGVycw==
ICAgICAgICAgICAgICAgICAgICAgICAgICBbIGZpZWxkcyBd
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IEFueSBmaWVsZCBub3QgYmVnaW5uaW5nIHdpdGg=
ICAgICAgICAgICAgICAgICAgICAgICAgICA7ICJjb250ZW50LSIgY2FuIGhhdmUgbm8gZGVmaW5lZA==
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IG1lYW5pbmcgYW5kIG1heSBiZSBpZ25vcmVkLg==
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IFRoZSBvcmRlcmluZyBvZiB0aGUgaGVhZGVy
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IGZpZWxkcyBpbXBsaWVkIGJ5IHRoaXMgQk5G
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IGRlZmluaXRpb24gc2hvdWxkIGJlIGlnbm9yZWQu
ICAgVGhlIHN5bnRheCBvZiB0aGUgdmFyaW91cyBzcGVjaWZpYyBNSU1FIGhlYWRlciBmaWVsZHMgd2lsbCBiZQ==
ICAgZGVzY3JpYmVkIGluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMu
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgW1BhZ2UgMTFd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
NS4xLiAgU3ludGF4IG9mIHRoZSBDb250ZW50LVR5cGUgSGVhZGVyIEZpZWxk
ICAgSW4gdGhlIEF1Z21lbnRlZCBCTkYgbm90YXRpb24gb2YgUkZDIDgyMiwgYSBDb250ZW50LVR5cGUgaGVhZGVyIGZpZWxk
ICAgdmFsdWUgaXMgZGVmaW5lZCBhcyBmb2xsb3dzOg==
ICAgICBjb250ZW50IDo9ICJDb250ZW50LVR5cGUiICI6IiB0eXBlICIvIiBzdWJ0eXBl
ICAgICAgICAgICAgICAgICooIjsiIHBhcmFtZXRlcik=
ICAgICAgICAgICAgICAgIDsgTWF0Y2hpbmcgb2YgbWVkaWEgdHlwZSBhbmQgc3VidHlwZQ==
ICAgICAgICAgICAgICAgIDsgaXMgQUxXQVlTIGNhc2UtaW5zZW5zaXRpdmUu
ICAgICB0eXBlIDo9IGRpc2NyZXRlLXR5cGUgLyBjb21wb3NpdGUtdHlwZQ==
ICAgICBkaXNjcmV0ZS10eXBlIDo9ICJ0ZXh0IiAvICJpbWFnZSIgLyAiYXVkaW8iIC8gInZpZGVvIiAv
ICAgICAgICAgICAgICAgICAgICAgICJhcHBsaWNhdGlvbiIgLyBleHRlbnNpb24tdG9rZW4=
ICAgICBjb21wb3NpdGUtdHlwZSA6PSAibWVzc2FnZSIgLyAibXVsdGlwYXJ0IiAvIGV4dGVuc2lvbi10b2tlbg==
ICAgICBleHRlbnNpb24tdG9rZW4gOj0gaWV0Zi10b2tlbiAvIHgtdG9rZW4=
ICAgICBpZXRmLXRva2VuIDo9IDxBbiBleHRlbnNpb24gdG9rZW4gZGVmaW5lZCBieSBh
ICAgICAgICAgICAgICAgICAgICBzdGFuZGFyZHMtdHJhY2sgUkZDIGFuZCByZWdpc3RlcmVk
ICAgICAgICAgICAgICAgICAgICB3aXRoIElBTkEuPg==
ICAgICB4LXRva2VuIDo9IDxUaGUgdHdvIGNoYXJhY3RlcnMgIlgtIiBvciAieC0iIGZvbGxvd2VkLCB3aXRo
ICAgICAgICAgICAgICAgICBubyBpbnRlcnZlbmluZyB3aGl0ZSBzcGFjZSwgYnkgYW55IHRva2VuPg==
ICAgICBzdWJ0eXBlIDo9IGV4dGVuc2lvbi10b2tlbiAvIGlhbmEtdG9rZW4=
ICAgICBpYW5hLXRva2VuIDo9IDxBIHB1YmxpY2x5LWRlZmluZWQgZXh0ZW5zaW9uIHRva2VuLiBUb2tlbnM=
ICAgICAgICAgICAgICAgICAgICBvZiB0aGlzIGZvcm0gbXVzdCBiZSByZWdpc3RlcmVkIHdpdGggSUFOQQ==
ICAgICAgICAgICAgICAgICAgICBhcyBzcGVjaWZpZWQgaW4gUkZDIDIwNDguPg==
ICAgICBwYXJhbWV0ZXIgOj0gYXR0cmlidXRlICI9IiB2YWx1ZQ==
ICAgICBhdHRyaWJ1dGUgOj0gdG9rZW4=
ICAgICAgICAgICAgICAgICAgOyBNYXRjaGluZyBvZiBhdHRyaWJ1dGVz
ICAgICAgICAgICAgICAgICAgOyBpcyBBTFdBWVMgY2FzZS1pbnNlbnNpdGl2ZS4=
ICAgICB2YWx1ZSA6PSB0b2tlbiAvIHF1b3RlZC1zdHJpbmc=
ICAgICB0b2tlbiA6PSAxKjxhbnkgKFVTLUFTQ0lJKSBDSEFSIGV4Y2VwdCBTUEFDRSwgQ1RMcyw=
ICAgICAgICAgICAgICAgICBvciB0c3BlY2lhbHM+
ICAgICB0c3BlY2lhbHMgOj0gICIoIiAvICIpIiAvICI8IiAvICI+IiAvICJAIiAv
ICAgICAgICAgICAgICAgICAgICIsIiAvICI7IiAvICI6IiAvICJcIiAvIDwiPg==
ICAgICAgICAgICAgICAgICAgICIvIiAvICJbIiAvICJdIiAvICI/IiAvICI9Ig==
ICAgICAgICAgICAgICAgICAgIDsgTXVzdCBiZSBpbiBxdW90ZWQtc3RyaW5nLA==
ICAgICAgICAgICAgICAgICAgIDsgdG8gdXNlIHdpdGhpbiBwYXJhbWV0ZXIgdmFsdWVz
ICAgICBkZXNjcmlwdGlvbiA6PSAiQ29udGVudC1EZXNjcmlwdGlvbiIgIjoiICp0ZXh0
ICAgICBlbmNvZGluZyA6PSAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyIgIjoiIG1lY2hhbmlzbQ==
ICAgICBlbnRpdHktaGVhZGVycyA6PSBbIGNvbnRlbnQgQ1JMRiBd
ICAgICAgICAgICAgICAgICAgICBbIGVuY29kaW5nIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICBbIGlkIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICBbIGRlc2NyaXB0aW9uIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICAqKCBNSU1FLWV4dGVuc2lvbi1maWVsZCBDUkxGICk=
ICAgICBoZXgtb2N0ZXQgOj0gIj0iIDIoRElHSVQgLyAiQSIgLyAiQiIgLyAiQyIgLyAiRCIgLyAiRSIgLyAiRiIp
ICAgICAgICAgICAgICAgOyBPY3RldCBtdXN0IGJlIHVzZWQgZm9yIGNoYXJhY3RlcnMgPiAxMjcsID0s
ICAgICAgICAgICAgICAgOyBTUEFDRXMgb3IgVEFCcyBhdCB0aGUgZW5kcyBvZiBsaW5lcywgYW5kIGlz
ICAgICAgICAgICAgICAgOyByZWNvbW1lbmRlZCBmb3IgYW55IGNoYXJhY3RlciBub3QgbGlzdGVkIGlu
ICAgICAgICAgICAgICAgOyBSRkMgMjA0OSBhcyAibWFpbC1zYWZlIi4=
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
ICAgICAgICAgIG11c3QgYmUgdXNlZC4gIEFuIGVxdWFsIHNpZ24gYXMgdGhlIGxhc3QgY2hhcmFjdGVyIG9uIGE=
ICAgICAgICAgIGVuY29kZWQgbGluZSBpbmRpY2F0ZXMgc3VjaCBhIG5vbi1zaWduaWZpY2FudCAoInNvZnQiKQ==
ICAgICAgICAgIGxpbmUgYnJlYWsgaW4gdGhlIGVuY29kZWQgdGV4dC4=
ICAgVGh1cyBpZiB0aGUgInJhdyIgZm9ybSBvZiB0aGUgbGluZSBpcyBhIHNpbmdsZSB1bmVuY29kZWQgbGluZSB0aGF0
ICAgc2F5czo=
ICAgICBOb3cncyB0aGUgdGltZSBmb3IgYWxsIGZvbGsgdG8gY29tZSB0byB0aGUgYWlkIG9mIHRoZWlyIGNvdW50cnku
ICAgVGhpcyBjYW4gYmUgcmVwcmVzZW50ZWQsIGluIHRoZSBRdW90ZWQtUHJpbnRhYmxlIGVuY29kaW5nLCBhczo=
ICAgICBOb3cncyB0aGUgdGltZSA9
ICAgICBmb3IgYWxsIGZvbGsgdG8gY29tZT0=
ICAgICAgdG8gdGhlIGFpZCBvZiB0aGVpciBjb3VudHJ5Lg==
ICAgU2luY2UgdGhlIGh5cGhlbiBjaGFyYWN0ZXIgKCItIikgbWF5IGJlIHJlcHJlc2VudGVkIGFzIGl0c2VsZiBpbiB0aGU=
ICAgUXVvdGVkLVByaW50YWJsZSBlbmNvZGluZywgY2FyZSBtdXN0IGJlIHRha2VuLCB3aGVuIGVuY2Fwc3VsYXRpbmcgYQ==
ICAgcXVvdGVkLXByaW50YWJsZSBlbmNvZGVkIGJvZHkgaW5zaWRlIG9uZSBvciBtb3JlIG11bHRpcGFydCBlbnRpdGllcyw=
ICAgdG8gZW5zdXJlIHRoYXQgdGhlIGJvdW5kYXJ5IGRlbGltaXRlciBkb2VzIG5vdCBhcHBlYXIgYW55d2hlcmUgaW4gdGhl
ICAgZW5jb2RlZCBib2R5LiAgKEEgZ29vZCBzdHJhdGVneSBpcyB0byBjaG9vc2UgYSBib3VuZGFyeSB0aGF0IGluY2x1ZGVz
ICAgYSBjaGFyYWN0ZXIgc2VxdWVuY2Ugc3VjaCBhcyAiPV8iIHdoaWNoIGNhbiBuZXZlciBhcHBlYXIgaW4gYQ==
ICAgcXVvdGVkLXByaW50YWJsZSBib2R5LiAgU2VlIHRoZSBkZWZpbml0aW9uIG9mIG11bHRpcGFydCBtZXNzYWdlcyBpbg==
ICAgUkZDIDIwNDYuKQ==
ICAgICAhIiMkQFtcXV5ge3x9fiU=
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgW1BhZ2UgMjRd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
ICAgICAgICAgICAgICAgICAgICBUYWJsZSAxOiBUaGUgQmFzZTY0IEFscGhhYmV0
ICAgICBWYWx1ZSBFbmNvZGluZyAgVmFsdWUgRW5jb2RpbmcgIFZhbHVlIEVuY29kaW5nICBWYWx1ZSBFbmNvZGluZw==
ICAgICAgICAgMCBBICAgICAgICAgICAgMTcgUiAgICAgICAgICAgIDM0IGkgICAgICAgICAgICA1MSB6
ICAgICAgICAgMSBCICAgICAgICAgICAgMTggUyAgICAgICAgICAgIDM1IGogICAgICAgICAgICA1MiAw
ICAgICAgICAgMiBDICAgICAgICAgICAgMTkgVCAgICAgICAgICAgIDM2IGsgICAgICAgICAgICA1MyAx
ICAgICAgICAgMyBEICAgICAgICAgICAgMjAgVSAgICAgICAgICAgIDM3IGwgICAgICAgICAgICA1NCAy
ICAgICAgICAgNCBFICAgICAgICAgICAgMjEgViAgICAgICAgICAgIDM4IG0gICAgICAgICAgICA1NSAz
ICAgICAgICAgNSBGICAgICAgICAgICAgMjIgVyAgICAgICAgICAgIDM5IG4gICAgICAgICAgICA1NiA0
ICAgICAgICAgNiBHICAgICAgICAgICAgMjMgWCAgICAgICAgICAgIDQwIG8gICAgICAgICAgICA1NyA1
ICAgICAgICAgNyBIICAgICAgICAgICAgMjQgWSAgICAgICAgICAgIDQxIHAgICAgICAgICAgICA1OCA2
ICAgICAgICAgOCBJICAgICAgICAgICAgMjUgWiAgICAgICAgICAgIDQyIHEgICAgICAgICAgICA1OSA3
ICAgICAgICAgOSBKICAgICAgICAgICAgMjYgYSAgICAgICAgICAgIDQzIHIgICAgICAgICAgICA2MCA4
ICAgICAgICAxMCBLICAgICAgICAgICAgMjcgYiAgICAgICAgICAgIDQ0IHMgICAgICAgICAgICA2MSA5
ICAgICAgICAxMSBMICAgICAgICAgICAgMjggYyAgICAgICAgICAgIDQ1IHQgICAgICAgICAgICA2MiAr
ICAgICAgICAxMiBNICAgICAgICAgICAgMjkgZCAgICAgICAgICAgIDQ2IHUgICAgICAgICAgICA2MyAv
ICAgICAgICAxMyBOICAgICAgICAgICAgMzAgZSAgICAgICAgICAgIDQ3IHY=
ICAgICAgICAxNCBPICAgICAgICAgICAgMzEgZiAgICAgICAgICAgIDQ4IHcgICAgICAgICAocGFkKSA9
ICAgICAgICAxNSBQICAgICAgICAgICAgMzIgZyAgICAgICAgICAgIDQ5IHg=
ICAgICAgICAxNiBRICAgICAgICAgICAgMzMgaCAgICAgICAgICAgIDUwIHk=
VGhpcyB0ZXN0IGRhdGEgaXMgcGFydCBvZiByZmMyMDQ1IHdoaWNoIGluY2x1ZGVzIGFsbCBjaGFy
YWN0ZXJzIGF+eiBBflosIDB+OSBhbmQgYWxsIHN5bWJvbHMs
SXQgaXMgdXNlZCB0byB0ZXN0IGphdmEudXRpbC5CYXNlNjQuRW5jb2RlciwgYW5kIHdpbGwgYmUg
ZW5jb2RlZCBieSBvcmcuYXBhY2hlLmNvbW1vbnMuY29kZWMuYmluYXJ5LkJhc2U2NC5qYXZh
dG8gdGVzdCBqYXZhLnV0aWwuQmFzZTY0LkRlY29kZXI7
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAg
ICAgICAgIFtQYWdlIDFd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAg
ICBOb3ZlbWJlciAxOTk2
ICAgVGhlc2UgZG9jdW1lbnRzIGFyZSByZXZpc2lvbnMgb2YgUkZDcyAxNTIxLCAxNTIyLCBhbmQg
MTU5MCwgd2hpY2g=
ICAgdGhlbXNlbHZlcyB3ZXJlIHJldmlzaW9ucyBvZiBSRkNzIDEzNDEgYW5kIDEzNDIuICBBbiBh
cHBlbmRpeCBpbiBSRkM=
ICAgMjA0OSBkZXNjcmliZXMgZGlmZmVyZW5jZXMgYW5kIGNoYW5nZXMgZnJvbSBwcmV2aW91cyB2
ZXJzaW9ucy4=
VGFibGUgb2YgQ29udGVudHM=
ICAgMS4gSW50cm9kdWN0aW9uIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgIDM=
ICAgMi4gRGVmaW5pdGlvbnMsIENvbnZlbnRpb25zLCBhbmQgR2VuZXJpYyBCTkYgR3JhbW1hciAu
Li4uICAgIDU=
ICAgMy4gTUlNRSBIZWFkZXIgRmllbGRzIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgIDg=
ICAgNC4gTUlNRS1WZXJzaW9uIEhlYWRlciBGaWVsZCAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgIDg=
ICAgNS4gQ29udGVudC1UeXBlIEhlYWRlciBGaWVsZCAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMTA=
ICAgNi4gQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4u
Li4uICAgMTQ=
ICAgNy4gQ29udGVudC1JRCBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMjY=
ICAgOC4gQ29udGVudC1EZXNjcmlwdGlvbiBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMjc=
ICAgOS4gQWRkaXRpb25hbCBNSU1FIEhlYWRlciBGaWVsZHMgLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMjc=
ICAgMTAuIFN1bW1hcnkgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMjc=
ICAgMTEuIFNlY3VyaXR5IENvbnNpZGVyYXRpb25zIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMjc=
ICAgMTIuIEF1dGhvcnMnIEFkZHJlc3NlcyAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMjg=
ICAgQS4gQ29sbGVjdGVkIEdyYW1tYXIgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4u
Li4uICAgMjk=
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAg
ICAgICAgIFtQYWdlIDdd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAg
ICBOb3ZlbWJlciAxOTk2
My4gIE1JTUUgSGVhZGVyIEZpZWxkcw==
ICAgTUlNRSBkZWZpbmVzIGEgbnVtYmVyIG9mIG5ldyBSRkMgODIyIGhlYWRlciBmaWVsZHMgdGhh
dCBhcmUgdXNlZCB0bw==
ICAgZGVzY3JpYmUgdGhlIGNvbnRlbnQgb2YgYSBNSU1FIGVudGl0eS4gIFRoZXNlIGhlYWRlciBm
aWVsZHMgb2NjdXIgaW4=
ICAgYXQgbGVhc3QgdHdvIGNvbnRleHRzOg==
ICAgICgxKSAgIEFzIHBhcnQgb2YgYSByZWd1bGFyIFJGQyA4MjIgbWVzc2FnZSBoZWFkZXIu
ICAgICgyKSAgIEluIGEgTUlNRSBib2R5IHBhcnQgaGVhZGVyIHdpdGhpbiBhIG11bHRpcGFydA==
ICAgICAgICAgIGNvbnN0cnVjdC4=
ICAgVGhlIGZvcm1hbCBkZWZpbml0aW9uIG9mIHRoZXNlIGhlYWRlciBmaWVsZHMgaXMgYXMgZm9s
bG93czo=
ICAgICBNSU1FLW1lc3NhZ2UtaGVhZGVycyA6PSBlbnRpdHktaGVhZGVycw==
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHM=
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uIENSTEY=
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IFRoZSBvcmRlcmluZyBvZiB0aGUgaGVhZGVy
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IGZpZWxkcyBpbXBsaWVkIGJ5IHRoaXMgQk5G
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IGRlZmluaXRpb24gc2hvdWxkIGJlIGlnbm9y
ZWQu
ICAgICBNSU1FLXBhcnQtaGVhZGVycyA6PSBlbnRpdHktaGVhZGVycw==
ICAgICAgICAgICAgICAgICAgICAgICAgICBbIGZpZWxkcyBd
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IEFueSBmaWVsZCBub3QgYmVnaW5uaW5nIHdpdGg=
ICAgICAgICAgICAgICAgICAgICAgICAgICA7ICJjb250ZW50LSIgY2FuIGhhdmUgbm8gZGVmaW5l
ZA==
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IG1lYW5pbmcgYW5kIG1heSBiZSBpZ25vcmVkLg==
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IFRoZSBvcmRlcmluZyBvZiB0aGUgaGVhZGVy
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IGZpZWxkcyBpbXBsaWVkIGJ5IHRoaXMgQk5G
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IGRlZmluaXRpb24gc2hvdWxkIGJlIGlnbm9yZWQu
ICAgVGhlIHN5bnRheCBvZiB0aGUgdmFyaW91cyBzcGVjaWZpYyBNSU1FIGhlYWRlciBmaWVsZHMg
d2lsbCBiZQ==
ICAgZGVzY3JpYmVkIGluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMu
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAg
ICAgICAgW1BhZ2UgMTFd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAg
ICBOb3ZlbWJlciAxOTk2
NS4xLiAgU3ludGF4IG9mIHRoZSBDb250ZW50LVR5cGUgSGVhZGVyIEZpZWxk
ICAgSW4gdGhlIEF1Z21lbnRlZCBCTkYgbm90YXRpb24gb2YgUkZDIDgyMiwgYSBDb250ZW50LVR5
cGUgaGVhZGVyIGZpZWxk
ICAgdmFsdWUgaXMgZGVmaW5lZCBhcyBmb2xsb3dzOg==
ICAgICBjb250ZW50IDo9ICJDb250ZW50LVR5cGUiICI6IiB0eXBlICIvIiBzdWJ0eXBl
ICAgICAgICAgICAgICAgICooIjsiIHBhcmFtZXRlcik=
ICAgICAgICAgICAgICAgIDsgTWF0Y2hpbmcgb2YgbWVkaWEgdHlwZSBhbmQgc3VidHlwZQ==
ICAgICAgICAgICAgICAgIDsgaXMgQUxXQVlTIGNhc2UtaW5zZW5zaXRpdmUu
ICAgICB0eXBlIDo9IGRpc2NyZXRlLXR5cGUgLyBjb21wb3NpdGUtdHlwZQ==
ICAgICBkaXNjcmV0ZS10eXBlIDo9ICJ0ZXh0IiAvICJpbWFnZSIgLyAiYXVkaW8iIC8gInZpZGVv
IiAv
ICAgICAgICAgICAgICAgICAgICAgICJhcHBsaWNhdGlvbiIgLyBleHRlbnNpb24tdG9rZW4=
ICAgICBjb21wb3NpdGUtdHlwZSA6PSAibWVzc2FnZSIgLyAibXVsdGlwYXJ0IiAvIGV4dGVuc2lv
bi10b2tlbg==
ICAgICBleHRlbnNpb24tdG9rZW4gOj0gaWV0Zi10b2tlbiAvIHgtdG9rZW4=
ICAgICBpZXRmLXRva2VuIDo9IDxBbiBleHRlbnNpb24gdG9rZW4gZGVmaW5lZCBieSBh
ICAgICAgICAgICAgICAgICAgICBzdGFuZGFyZHMtdHJhY2sgUkZDIGFuZCByZWdpc3RlcmVk
ICAgICAgICAgICAgICAgICAgICB3aXRoIElBTkEuPg==
ICAgICB4LXRva2VuIDo9IDxUaGUgdHdvIGNoYXJhY3RlcnMgIlgtIiBvciAieC0iIGZvbGxvd2Vk
LCB3aXRo
ICAgICAgICAgICAgICAgICBubyBpbnRlcnZlbmluZyB3aGl0ZSBzcGFjZSwgYnkgYW55IHRva2Vu
Pg==
ICAgICBzdWJ0eXBlIDo9IGV4dGVuc2lvbi10b2tlbiAvIGlhbmEtdG9rZW4=
ICAgICBpYW5hLXRva2VuIDo9IDxBIHB1YmxpY2x5LWRlZmluZWQgZXh0ZW5zaW9uIHRva2VuLiBU
b2tlbnM=
ICAgICAgICAgICAgICAgICAgICBvZiB0aGlzIGZvcm0gbXVzdCBiZSByZWdpc3RlcmVkIHdpdGgg
SUFOQQ==
ICAgICAgICAgICAgICAgICAgICBhcyBzcGVjaWZpZWQgaW4gUkZDIDIwNDguPg==
ICAgICBwYXJhbWV0ZXIgOj0gYXR0cmlidXRlICI9IiB2YWx1ZQ==
ICAgICBhdHRyaWJ1dGUgOj0gdG9rZW4=
ICAgICAgICAgICAgICAgICAgOyBNYXRjaGluZyBvZiBhdHRyaWJ1dGVz
ICAgICAgICAgICAgICAgICAgOyBpcyBBTFdBWVMgY2FzZS1pbnNlbnNpdGl2ZS4=
ICAgICB2YWx1ZSA6PSB0b2tlbiAvIHF1b3RlZC1zdHJpbmc=
ICAgICB0b2tlbiA6PSAxKjxhbnkgKFVTLUFTQ0lJKSBDSEFSIGV4Y2VwdCBTUEFDRSwgQ1RMcyw=
ICAgICAgICAgICAgICAgICBvciB0c3BlY2lhbHM+
ICAgICB0c3BlY2lhbHMgOj0gICIoIiAvICIpIiAvICI8IiAvICI+IiAvICJAIiAv
ICAgICAgICAgICAgICAgICAgICIsIiAvICI7IiAvICI6IiAvICJcIiAvIDwiPg==
ICAgICAgICAgICAgICAgICAgICIvIiAvICJbIiAvICJdIiAvICI/IiAvICI9Ig==
ICAgICAgICAgICAgICAgICAgIDsgTXVzdCBiZSBpbiBxdW90ZWQtc3RyaW5nLA==
ICAgICAgICAgICAgICAgICAgIDsgdG8gdXNlIHdpdGhpbiBwYXJhbWV0ZXIgdmFsdWVz
ICAgICBkZXNjcmlwdGlvbiA6PSAiQ29udGVudC1EZXNjcmlwdGlvbiIgIjoiICp0ZXh0
ICAgICBlbmNvZGluZyA6PSAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyIgIjoiIG1lY2hhbmlz
bQ==
ICAgICBlbnRpdHktaGVhZGVycyA6PSBbIGNvbnRlbnQgQ1JMRiBd
ICAgICAgICAgICAgICAgICAgICBbIGVuY29kaW5nIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICBbIGlkIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICBbIGRlc2NyaXB0aW9uIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICAqKCBNSU1FLWV4dGVuc2lvbi1maWVsZCBDUkxGICk=
ICAgICBoZXgtb2N0ZXQgOj0gIj0iIDIoRElHSVQgLyAiQSIgLyAiQiIgLyAiQyIgLyAiRCIgLyAi
RSIgLyAiRiIp
ICAgICAgICAgICAgICAgOyBPY3RldCBtdXN0IGJlIHVzZWQgZm9yIGNoYXJhY3RlcnMgPiAxMjcs
ID0s
ICAgICAgICAgICAgICAgOyBTUEFDRXMgb3IgVEFCcyBhdCB0aGUgZW5kcyBvZiBsaW5lcywgYW5k
IGlz
ICAgICAgICAgICAgICAgOyByZWNvbW1lbmRlZCBmb3IgYW55IGNoYXJhY3RlciBub3QgbGlzdGVk
IGlu
ICAgICAgICAgICAgICAgOyBSRkMgMjA0OSBhcyAibWFpbC1zYWZlIi4=
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAg
ICBOb3ZlbWJlciAxOTk2
ICAgICAgICAgIG11c3QgYmUgdXNlZC4gIEFuIGVxdWFsIHNpZ24gYXMgdGhlIGxhc3QgY2hhcmFj
dGVyIG9uIGE=
ICAgICAgICAgIGVuY29kZWQgbGluZSBpbmRpY2F0ZXMgc3VjaCBhIG5vbi1zaWduaWZpY2FudCAo
InNvZnQiKQ==
ICAgICAgICAgIGxpbmUgYnJlYWsgaW4gdGhlIGVuY29kZWQgdGV4dC4=
ICAgVGh1cyBpZiB0aGUgInJhdyIgZm9ybSBvZiB0aGUgbGluZSBpcyBhIHNpbmdsZSB1bmVuY29k
ZWQgbGluZSB0aGF0
ICAgc2F5czo=
ICAgICBOb3cncyB0aGUgdGltZSBmb3IgYWxsIGZvbGsgdG8gY29tZSB0byB0aGUgYWlkIG9mIHRo
ZWlyIGNvdW50cnku
ICAgVGhpcyBjYW4gYmUgcmVwcmVzZW50ZWQsIGluIHRoZSBRdW90ZWQtUHJpbnRhYmxlIGVuY29k
aW5nLCBhczo=
ICAgICBOb3cncyB0aGUgdGltZSA9
ICAgICBmb3IgYWxsIGZvbGsgdG8gY29tZT0=
ICAgICAgdG8gdGhlIGFpZCBvZiB0aGVpciBjb3VudHJ5Lg==
ICAgU2luY2UgdGhlIGh5cGhlbiBjaGFyYWN0ZXIgKCItIikgbWF5IGJlIHJlcHJlc2VudGVkIGFz
IGl0c2VsZiBpbiB0aGU=
ICAgUXVvdGVkLVByaW50YWJsZSBlbmNvZGluZywgY2FyZSBtdXN0IGJlIHRha2VuLCB3aGVuIGVu
Y2Fwc3VsYXRpbmcgYQ==
ICAgcXVvdGVkLXByaW50YWJsZSBlbmNvZGVkIGJvZHkgaW5zaWRlIG9uZSBvciBtb3JlIG11bHRp
cGFydCBlbnRpdGllcyw=
ICAgdG8gZW5zdXJlIHRoYXQgdGhlIGJvdW5kYXJ5IGRlbGltaXRlciBkb2VzIG5vdCBhcHBlYXIg
YW55d2hlcmUgaW4gdGhl
ICAgZW5jb2RlZCBib2R5LiAgKEEgZ29vZCBzdHJhdGVneSBpcyB0byBjaG9vc2UgYSBib3VuZGFy
eSB0aGF0IGluY2x1ZGVz
ICAgYSBjaGFyYWN0ZXIgc2VxdWVuY2Ugc3VjaCBhcyAiPV8iIHdoaWNoIGNhbiBuZXZlciBhcHBl
YXIgaW4gYQ==
ICAgcXVvdGVkLXByaW50YWJsZSBib2R5LiAgU2VlIHRoZSBkZWZpbml0aW9uIG9mIG11bHRpcGFy
dCBtZXNzYWdlcyBpbg==
ICAgUkZDIDIwNDYuKQ==
ICAgICAhIiMkQFtcXV5ge3x9fiU=
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAg
ICAgICAgW1BhZ2UgMjRd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAg
ICBOb3ZlbWJlciAxOTk2
ICAgICAgICAgICAgICAgICAgICBUYWJsZSAxOiBUaGUgQmFzZTY0IEFscGhhYmV0
ICAgICBWYWx1ZSBFbmNvZGluZyAgVmFsdWUgRW5jb2RpbmcgIFZhbHVlIEVuY29kaW5nICBWYWx1
ZSBFbmNvZGluZw==
ICAgICAgICAgMCBBICAgICAgICAgICAgMTcgUiAgICAgICAgICAgIDM0IGkgICAgICAgICAgICA1
MSB6
ICAgICAgICAgMSBCICAgICAgICAgICAgMTggUyAgICAgICAgICAgIDM1IGogICAgICAgICAgICA1
MiAw
ICAgICAgICAgMiBDICAgICAgICAgICAgMTkgVCAgICAgICAgICAgIDM2IGsgICAgICAgICAgICA1
MyAx
ICAgICAgICAgMyBEICAgICAgICAgICAgMjAgVSAgICAgICAgICAgIDM3IGwgICAgICAgICAgICA1
NCAy
ICAgICAgICAgNCBFICAgICAgICAgICAgMjEgViAgICAgICAgICAgIDM4IG0gICAgICAgICAgICA1
NSAz
ICAgICAgICAgNSBGICAgICAgICAgICAgMjIgVyAgICAgICAgICAgIDM5IG4gICAgICAgICAgICA1
NiA0
ICAgICAgICAgNiBHICAgICAgICAgICAgMjMgWCAgICAgICAgICAgIDQwIG8gICAgICAgICAgICA1
NyA1
ICAgICAgICAgNyBIICAgICAgICAgICAgMjQgWSAgICAgICAgICAgIDQxIHAgICAgICAgICAgICA1
OCA2
ICAgICAgICAgOCBJICAgICAgICAgICAgMjUgWiAgICAgICAgICAgIDQyIHEgICAgICAgICAgICA1
OSA3
ICAgICAgICAgOSBKICAgICAgICAgICAgMjYgYSAgICAgICAgICAgIDQzIHIgICAgICAgICAgICA2
MCA4
ICAgICAgICAxMCBLICAgICAgICAgICAgMjcgYiAgICAgICAgICAgIDQ0IHMgICAgICAgICAgICA2
MSA5
ICAgICAgICAxMSBMICAgICAgICAgICAgMjggYyAgICAgICAgICAgIDQ1IHQgICAgICAgICAgICA2
MiAr
ICAgICAgICAxMiBNICAgICAgICAgICAgMjkgZCAgICAgICAgICAgIDQ2IHUgICAgICAgICAgICA2
MyAv
ICAgICAgICAxMyBOICAgICAgICAgICAgMzAgZSAgICAgICAgICAgIDQ3IHY=
ICAgICAgICAxNCBPICAgICAgICAgICAgMzEgZiAgICAgICAgICAgIDQ4IHcgICAgICAgICAocGFk
KSA9
ICAgICAgICAxNSBQICAgICAgICAgICAgMzIgZyAgICAgICAgICAgIDQ5IHg=
ICAgICAgICAxNiBRICAgICAgICAgICAgMzMgaCAgICAgICAgICAgIDUwIHk=
This test data is part of rfc2045 which includes all characters a~z A~Z, 0~9 and all symbols,
It is used to test java.util.Base64.Encoder, and will be encoded by org.apache.commons.codec.binary.Base64.java
to test java.util.Base64.Decoder;
Freed & Borenstein Standards Track [Page 1]
RFC 2045 Internet Message Bodies November 1996
These documents are revisions of RFCs 1521, 1522, and 1590, which
themselves were revisions of RFCs 1341 and 1342. An appendix in RFC
2049 describes differences and changes from previous versions.
Table of Contents
1. Introduction ......................................... 3
2. Definitions, Conventions, and Generic BNF Grammar .... 5
3. MIME Header Fields ................................... 8
4. MIME-Version Header Field ............................ 8
5. Content-Type Header Field ............................ 10
6. Content-Transfer-Encoding Header Field ............... 14
7. Content-ID Header Field .............................. 26
8. Content-Description Header Field ..................... 27
9. Additional MIME Header Fields ........................ 27
10. Summary ............................................. 27
11. Security Considerations ............................. 27
12. Authors' Addresses .................................. 28
A. Collected Grammar .................................... 29
Freed & Borenstein Standards Track [Page 7]
RFC 2045 Internet Message Bodies November 1996
3. MIME Header Fields
MIME defines a number of new RFC 822 header fields that are used to
describe the content of a MIME entity. These header fields occur in
at least two contexts:
(1) As part of a regular RFC 822 message header.
(2) In a MIME body part header within a multipart
construct.
The formal definition of these header fields is as follows:
MIME-message-headers := entity-headers
fields
version CRLF
; The ordering of the header
; fields implied by this BNF
; definition should be ignored.
MIME-part-headers := entity-headers
[ fields ]
; Any field not beginning with
; "content-" can have no defined
; meaning and may be ignored.
; The ordering of the header
; fields implied by this BNF
; definition should be ignored.
The syntax of the various specific MIME header fields will be
described in the following sections.
Freed & Borenstein Standards Track [Page 11]
RFC 2045 Internet Message Bodies November 1996
5.1. Syntax of the Content-Type Header Field
In the Augmented BNF notation of RFC 822, a Content-Type header field
value is defined as follows:
content := "Content-Type" ":" type "/" subtype
*(";" parameter)
; Matching of media type and subtype
; is ALWAYS case-insensitive.
type := discrete-type / composite-type
discrete-type := "text" / "image" / "audio" / "video" /
"application" / extension-token
composite-type := "message" / "multipart" / extension-token
extension-token := ietf-token / x-token
ietf-token := <An extension token defined by a
standards-track RFC and registered
with IANA.>
x-token := <The two characters "X-" or "x-" followed, with
no intervening white space, by any token>
subtype := extension-token / iana-token
iana-token := <A publicly-defined extension token. Tokens
of this form must be registered with IANA
as specified in RFC 2048.>
parameter := attribute "=" value
attribute := token
; Matching of attributes
; is ALWAYS case-insensitive.
value := token / quoted-string
token := 1*<any (US-ASCII) CHAR except SPACE, CTLs,
or tspecials>
tspecials := "(" / ")" / "<" / ">" / "@" /
"," / ";" / ":" / "\" / <">
"/" / "[" / "]" / "?" / "="
; Must be in quoted-string,
; to use within parameter values
description := "Content-Description" ":" *text
encoding := "Content-Transfer-Encoding" ":" mechanism
entity-headers := [ content CRLF ]
[ encoding CRLF ]
[ id CRLF ]
[ description CRLF ]
*( MIME-extension-field CRLF )
hex-octet := "=" 2(DIGIT / "A" / "B" / "C" / "D" / "E" / "F")
; Octet must be used for characters > 127, =,
; SPACEs or TABs at the ends of lines, and is
; recommended for any character not listed in
; RFC 2049 as "mail-safe".
RFC 2045 Internet Message Bodies November 1996
must be used. An equal sign as the last character on a
encoded line indicates such a non-significant ("soft")
line break in the encoded text.
Thus if the "raw" form of the line is a single unencoded line that
says:
Now's the time for all folk to come to the aid of their country.
This can be represented, in the Quoted-Printable encoding, as:
Now's the time =
for all folk to come=
to the aid of their country.
Since the hyphen character ("-") may be represented as itself in the
Quoted-Printable encoding, care must be taken, when encapsulating a
quoted-printable encoded body inside one or more multipart entities,
to ensure that the boundary delimiter does not appear anywhere in the
encoded body. (A good strategy is to choose a boundary that includes
a character sequence such as "=_" which can never appear in a
quoted-printable body. See the definition of multipart messages in
RFC 2046.)
!"#$@[\]^`{|}~%
Freed & Borenstein Standards Track [Page 24]
RFC 2045 Internet Message Bodies November 1996
Table 1: The Base64 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 G 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
14 O 31 f 48 w (pad) =
15 P 32 g 49 x
16 Q 33 h 50 y
VGhpcyB0ZXN0IGRhdGEgaXMgcGFydCBvZiByZmMyMDQ1IHdoaWNoIGluY2x1ZGVzIGFsbCBjaGFyYWN0ZXJzIGF-eiBBflosIDB-OSBhbmQgYWxsIHN5bWJvbHMs
SXQgaXMgdXNlZCB0byB0ZXN0IGphdmEudXRpbC5CYXNlNjQuRW5jb2RlciwgYW5kIHdpbGwgYmUgZW5jb2RlZCBieSBvcmcuYXBhY2hlLmNvbW1vbnMuY29kZWMuYmluYXJ5LkJhc2U2NC5qYXZh
dG8gdGVzdCBqYXZhLnV0aWwuQmFzZTY0LkRlY29kZXI7
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgIFtQYWdlIDFd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
ICAgVGhlc2UgZG9jdW1lbnRzIGFyZSByZXZpc2lvbnMgb2YgUkZDcyAxNTIxLCAxNTIyLCBhbmQgMTU5MCwgd2hpY2g=
ICAgdGhlbXNlbHZlcyB3ZXJlIHJldmlzaW9ucyBvZiBSRkNzIDEzNDEgYW5kIDEzNDIuICBBbiBhcHBlbmRpeCBpbiBSRkM=
ICAgMjA0OSBkZXNjcmliZXMgZGlmZmVyZW5jZXMgYW5kIGNoYW5nZXMgZnJvbSBwcmV2aW91cyB2ZXJzaW9ucy4=
VGFibGUgb2YgQ29udGVudHM=
ICAgMS4gSW50cm9kdWN0aW9uIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgIDM=
ICAgMi4gRGVmaW5pdGlvbnMsIENvbnZlbnRpb25zLCBhbmQgR2VuZXJpYyBCTkYgR3JhbW1hciAuLi4uICAgIDU=
ICAgMy4gTUlNRSBIZWFkZXIgRmllbGRzIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgIDg=
ICAgNC4gTUlNRS1WZXJzaW9uIEhlYWRlciBGaWVsZCAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgIDg=
ICAgNS4gQ29udGVudC1UeXBlIEhlYWRlciBGaWVsZCAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMTA=
ICAgNi4gQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uICAgMTQ=
ICAgNy4gQ29udGVudC1JRCBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjY=
ICAgOC4gQ29udGVudC1EZXNjcmlwdGlvbiBIZWFkZXIgRmllbGQgLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgOS4gQWRkaXRpb25hbCBNSU1FIEhlYWRlciBGaWVsZHMgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgMTAuIFN1bW1hcnkgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgMTEuIFNlY3VyaXR5IENvbnNpZGVyYXRpb25zIC4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjc=
ICAgMTIuIEF1dGhvcnMnIEFkZHJlc3NlcyAuLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjg=
ICAgQS4gQ29sbGVjdGVkIEdyYW1tYXIgLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uICAgMjk=
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgIFtQYWdlIDdd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
My4gIE1JTUUgSGVhZGVyIEZpZWxkcw==
ICAgTUlNRSBkZWZpbmVzIGEgbnVtYmVyIG9mIG5ldyBSRkMgODIyIGhlYWRlciBmaWVsZHMgdGhhdCBhcmUgdXNlZCB0bw==
ICAgZGVzY3JpYmUgdGhlIGNvbnRlbnQgb2YgYSBNSU1FIGVudGl0eS4gIFRoZXNlIGhlYWRlciBmaWVsZHMgb2NjdXIgaW4=
ICAgYXQgbGVhc3QgdHdvIGNvbnRleHRzOg==
ICAgICgxKSAgIEFzIHBhcnQgb2YgYSByZWd1bGFyIFJGQyA4MjIgbWVzc2FnZSBoZWFkZXIu
ICAgICgyKSAgIEluIGEgTUlNRSBib2R5IHBhcnQgaGVhZGVyIHdpdGhpbiBhIG11bHRpcGFydA==
ICAgICAgICAgIGNvbnN0cnVjdC4=
ICAgVGhlIGZvcm1hbCBkZWZpbml0aW9uIG9mIHRoZXNlIGhlYWRlciBmaWVsZHMgaXMgYXMgZm9sbG93czo=
ICAgICBNSU1FLW1lc3NhZ2UtaGVhZGVycyA6PSBlbnRpdHktaGVhZGVycw==
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZHM=
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2ZXJzaW9uIENSTEY=
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IFRoZSBvcmRlcmluZyBvZiB0aGUgaGVhZGVy
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IGZpZWxkcyBpbXBsaWVkIGJ5IHRoaXMgQk5G
ICAgICAgICAgICAgICAgICAgICAgICAgICAgICA7IGRlZmluaXRpb24gc2hvdWxkIGJlIGlnbm9yZWQu
ICAgICBNSU1FLXBhcnQtaGVhZGVycyA6PSBlbnRpdHktaGVhZGVycw==
ICAgICAgICAgICAgICAgICAgICAgICAgICBbIGZpZWxkcyBd
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IEFueSBmaWVsZCBub3QgYmVnaW5uaW5nIHdpdGg=
ICAgICAgICAgICAgICAgICAgICAgICAgICA7ICJjb250ZW50LSIgY2FuIGhhdmUgbm8gZGVmaW5lZA==
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IG1lYW5pbmcgYW5kIG1heSBiZSBpZ25vcmVkLg==
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IFRoZSBvcmRlcmluZyBvZiB0aGUgaGVhZGVy
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IGZpZWxkcyBpbXBsaWVkIGJ5IHRoaXMgQk5G
ICAgICAgICAgICAgICAgICAgICAgICAgICA7IGRlZmluaXRpb24gc2hvdWxkIGJlIGlnbm9yZWQu
ICAgVGhlIHN5bnRheCBvZiB0aGUgdmFyaW91cyBzcGVjaWZpYyBNSU1FIGhlYWRlciBmaWVsZHMgd2lsbCBiZQ==
ICAgZGVzY3JpYmVkIGluIHRoZSBmb2xsb3dpbmcgc2VjdGlvbnMu
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgW1BhZ2UgMTFd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
NS4xLiAgU3ludGF4IG9mIHRoZSBDb250ZW50LVR5cGUgSGVhZGVyIEZpZWxk
ICAgSW4gdGhlIEF1Z21lbnRlZCBCTkYgbm90YXRpb24gb2YgUkZDIDgyMiwgYSBDb250ZW50LVR5cGUgaGVhZGVyIGZpZWxk
ICAgdmFsdWUgaXMgZGVmaW5lZCBhcyBmb2xsb3dzOg==
ICAgICBjb250ZW50IDo9ICJDb250ZW50LVR5cGUiICI6IiB0eXBlICIvIiBzdWJ0eXBl
ICAgICAgICAgICAgICAgICooIjsiIHBhcmFtZXRlcik=
ICAgICAgICAgICAgICAgIDsgTWF0Y2hpbmcgb2YgbWVkaWEgdHlwZSBhbmQgc3VidHlwZQ==
ICAgICAgICAgICAgICAgIDsgaXMgQUxXQVlTIGNhc2UtaW5zZW5zaXRpdmUu
ICAgICB0eXBlIDo9IGRpc2NyZXRlLXR5cGUgLyBjb21wb3NpdGUtdHlwZQ==
ICAgICBkaXNjcmV0ZS10eXBlIDo9ICJ0ZXh0IiAvICJpbWFnZSIgLyAiYXVkaW8iIC8gInZpZGVvIiAv
ICAgICAgICAgICAgICAgICAgICAgICJhcHBsaWNhdGlvbiIgLyBleHRlbnNpb24tdG9rZW4=
ICAgICBjb21wb3NpdGUtdHlwZSA6PSAibWVzc2FnZSIgLyAibXVsdGlwYXJ0IiAvIGV4dGVuc2lvbi10b2tlbg==
ICAgICBleHRlbnNpb24tdG9rZW4gOj0gaWV0Zi10b2tlbiAvIHgtdG9rZW4=
ICAgICBpZXRmLXRva2VuIDo9IDxBbiBleHRlbnNpb24gdG9rZW4gZGVmaW5lZCBieSBh
ICAgICAgICAgICAgICAgICAgICBzdGFuZGFyZHMtdHJhY2sgUkZDIGFuZCByZWdpc3RlcmVk
ICAgICAgICAgICAgICAgICAgICB3aXRoIElBTkEuPg==
ICAgICB4LXRva2VuIDo9IDxUaGUgdHdvIGNoYXJhY3RlcnMgIlgtIiBvciAieC0iIGZvbGxvd2VkLCB3aXRo
ICAgICAgICAgICAgICAgICBubyBpbnRlcnZlbmluZyB3aGl0ZSBzcGFjZSwgYnkgYW55IHRva2VuPg==
ICAgICBzdWJ0eXBlIDo9IGV4dGVuc2lvbi10b2tlbiAvIGlhbmEtdG9rZW4=
ICAgICBpYW5hLXRva2VuIDo9IDxBIHB1YmxpY2x5LWRlZmluZWQgZXh0ZW5zaW9uIHRva2VuLiBUb2tlbnM=
ICAgICAgICAgICAgICAgICAgICBvZiB0aGlzIGZvcm0gbXVzdCBiZSByZWdpc3RlcmVkIHdpdGggSUFOQQ==
ICAgICAgICAgICAgICAgICAgICBhcyBzcGVjaWZpZWQgaW4gUkZDIDIwNDguPg==
ICAgICBwYXJhbWV0ZXIgOj0gYXR0cmlidXRlICI9IiB2YWx1ZQ==
ICAgICBhdHRyaWJ1dGUgOj0gdG9rZW4=
ICAgICAgICAgICAgICAgICAgOyBNYXRjaGluZyBvZiBhdHRyaWJ1dGVz
ICAgICAgICAgICAgICAgICAgOyBpcyBBTFdBWVMgY2FzZS1pbnNlbnNpdGl2ZS4=
ICAgICB2YWx1ZSA6PSB0b2tlbiAvIHF1b3RlZC1zdHJpbmc=
ICAgICB0b2tlbiA6PSAxKjxhbnkgKFVTLUFTQ0lJKSBDSEFSIGV4Y2VwdCBTUEFDRSwgQ1RMcyw=
ICAgICAgICAgICAgICAgICBvciB0c3BlY2lhbHM-
ICAgICB0c3BlY2lhbHMgOj0gICIoIiAvICIpIiAvICI8IiAvICI-IiAvICJAIiAv
ICAgICAgICAgICAgICAgICAgICIsIiAvICI7IiAvICI6IiAvICJcIiAvIDwiPg==
ICAgICAgICAgICAgICAgICAgICIvIiAvICJbIiAvICJdIiAvICI_IiAvICI9Ig==
ICAgICAgICAgICAgICAgICAgIDsgTXVzdCBiZSBpbiBxdW90ZWQtc3RyaW5nLA==
ICAgICAgICAgICAgICAgICAgIDsgdG8gdXNlIHdpdGhpbiBwYXJhbWV0ZXIgdmFsdWVz
ICAgICBkZXNjcmlwdGlvbiA6PSAiQ29udGVudC1EZXNjcmlwdGlvbiIgIjoiICp0ZXh0
ICAgICBlbmNvZGluZyA6PSAiQ29udGVudC1UcmFuc2Zlci1FbmNvZGluZyIgIjoiIG1lY2hhbmlzbQ==
ICAgICBlbnRpdHktaGVhZGVycyA6PSBbIGNvbnRlbnQgQ1JMRiBd
ICAgICAgICAgICAgICAgICAgICBbIGVuY29kaW5nIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICBbIGlkIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICBbIGRlc2NyaXB0aW9uIENSTEYgXQ==
ICAgICAgICAgICAgICAgICAgICAqKCBNSU1FLWV4dGVuc2lvbi1maWVsZCBDUkxGICk=
ICAgICBoZXgtb2N0ZXQgOj0gIj0iIDIoRElHSVQgLyAiQSIgLyAiQiIgLyAiQyIgLyAiRCIgLyAiRSIgLyAiRiIp
ICAgICAgICAgICAgICAgOyBPY3RldCBtdXN0IGJlIHVzZWQgZm9yIGNoYXJhY3RlcnMgPiAxMjcsID0s
ICAgICAgICAgICAgICAgOyBTUEFDRXMgb3IgVEFCcyBhdCB0aGUgZW5kcyBvZiBsaW5lcywgYW5kIGlz
ICAgICAgICAgICAgICAgOyByZWNvbW1lbmRlZCBmb3IgYW55IGNoYXJhY3RlciBub3QgbGlzdGVkIGlu
ICAgICAgICAgICAgICAgOyBSRkMgMjA0OSBhcyAibWFpbC1zYWZlIi4=
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
ICAgICAgICAgIG11c3QgYmUgdXNlZC4gIEFuIGVxdWFsIHNpZ24gYXMgdGhlIGxhc3QgY2hhcmFjdGVyIG9uIGE=
ICAgICAgICAgIGVuY29kZWQgbGluZSBpbmRpY2F0ZXMgc3VjaCBhIG5vbi1zaWduaWZpY2FudCAoInNvZnQiKQ==
ICAgICAgICAgIGxpbmUgYnJlYWsgaW4gdGhlIGVuY29kZWQgdGV4dC4=
ICAgVGh1cyBpZiB0aGUgInJhdyIgZm9ybSBvZiB0aGUgbGluZSBpcyBhIHNpbmdsZSB1bmVuY29kZWQgbGluZSB0aGF0
ICAgc2F5czo=
ICAgICBOb3cncyB0aGUgdGltZSBmb3IgYWxsIGZvbGsgdG8gY29tZSB0byB0aGUgYWlkIG9mIHRoZWlyIGNvdW50cnku
ICAgVGhpcyBjYW4gYmUgcmVwcmVzZW50ZWQsIGluIHRoZSBRdW90ZWQtUHJpbnRhYmxlIGVuY29kaW5nLCBhczo=
ICAgICBOb3cncyB0aGUgdGltZSA9
ICAgICBmb3IgYWxsIGZvbGsgdG8gY29tZT0=
ICAgICAgdG8gdGhlIGFpZCBvZiB0aGVpciBjb3VudHJ5Lg==
ICAgU2luY2UgdGhlIGh5cGhlbiBjaGFyYWN0ZXIgKCItIikgbWF5IGJlIHJlcHJlc2VudGVkIGFzIGl0c2VsZiBpbiB0aGU=
ICAgUXVvdGVkLVByaW50YWJsZSBlbmNvZGluZywgY2FyZSBtdXN0IGJlIHRha2VuLCB3aGVuIGVuY2Fwc3VsYXRpbmcgYQ==
ICAgcXVvdGVkLXByaW50YWJsZSBlbmNvZGVkIGJvZHkgaW5zaWRlIG9uZSBvciBtb3JlIG11bHRpcGFydCBlbnRpdGllcyw=
ICAgdG8gZW5zdXJlIHRoYXQgdGhlIGJvdW5kYXJ5IGRlbGltaXRlciBkb2VzIG5vdCBhcHBlYXIgYW55d2hlcmUgaW4gdGhl
ICAgZW5jb2RlZCBib2R5LiAgKEEgZ29vZCBzdHJhdGVneSBpcyB0byBjaG9vc2UgYSBib3VuZGFyeSB0aGF0IGluY2x1ZGVz
ICAgYSBjaGFyYWN0ZXIgc2VxdWVuY2Ugc3VjaCBhcyAiPV8iIHdoaWNoIGNhbiBuZXZlciBhcHBlYXIgaW4gYQ==
ICAgcXVvdGVkLXByaW50YWJsZSBib2R5LiAgU2VlIHRoZSBkZWZpbml0aW9uIG9mIG11bHRpcGFydCBtZXNzYWdlcyBpbg==
ICAgUkZDIDIwNDYuKQ==
ICAgICAhIiMkQFtcXV5ge3x9fiU=
RnJlZWQgJiBCb3JlbnN0ZWluICAgICAgICAgIFN0YW5kYXJkcyBUcmFjayAgICAgICAgICAgICAgICAgICAgW1BhZ2UgMjRd
UkZDIDIwNDUgICAgICAgICAgICAgICAgSW50ZXJuZXQgTWVzc2FnZSBCb2RpZXMgICAgICAgICAgICBOb3ZlbWJlciAxOTk2
ICAgICAgICAgICAgICAgICAgICBUYWJsZSAxOiBUaGUgQmFzZTY0IEFscGhhYmV0
ICAgICBWYWx1ZSBFbmNvZGluZyAgVmFsdWUgRW5jb2RpbmcgIFZhbHVlIEVuY29kaW5nICBWYWx1ZSBFbmNvZGluZw==
ICAgICAgICAgMCBBICAgICAgICAgICAgMTcgUiAgICAgICAgICAgIDM0IGkgICAgICAgICAgICA1MSB6
ICAgICAgICAgMSBCICAgICAgICAgICAgMTggUyAgICAgICAgICAgIDM1IGogICAgICAgICAgICA1MiAw
ICAgICAgICAgMiBDICAgICAgICAgICAgMTkgVCAgICAgICAgICAgIDM2IGsgICAgICAgICAgICA1MyAx
ICAgICAgICAgMyBEICAgICAgICAgICAgMjAgVSAgICAgICAgICAgIDM3IGwgICAgICAgICAgICA1NCAy
ICAgICAgICAgNCBFICAgICAgICAgICAgMjEgViAgICAgICAgICAgIDM4IG0gICAgICAgICAgICA1NSAz
ICAgICAgICAgNSBGICAgICAgICAgICAgMjIgVyAgICAgICAgICAgIDM5IG4gICAgICAgICAgICA1NiA0
ICAgICAgICAgNiBHICAgICAgICAgICAgMjMgWCAgICAgICAgICAgIDQwIG8gICAgICAgICAgICA1NyA1
ICAgICAgICAgNyBIICAgICAgICAgICAgMjQgWSAgICAgICAgICAgIDQxIHAgICAgICAgICAgICA1OCA2
ICAgICAgICAgOCBJICAgICAgICAgICAgMjUgWiAgICAgICAgICAgIDQyIHEgICAgICAgICAgICA1OSA3
ICAgICAgICAgOSBKICAgICAgICAgICAgMjYgYSAgICAgICAgICAgIDQzIHIgICAgICAgICAgICA2MCA4
ICAgICAgICAxMCBLICAgICAgICAgICAgMjcgYiAgICAgICAgICAgIDQ0IHMgICAgICAgICAgICA2MSA5
ICAgICAgICAxMSBMICAgICAgICAgICAgMjggYyAgICAgICAgICAgIDQ1IHQgICAgICAgICAgICA2MiAr
ICAgICAgICAxMiBNICAgICAgICAgICAgMjkgZCAgICAgICAgICAgIDQ2IHUgICAgICAgICAgICA2MyAv
ICAgICAgICAxMyBOICAgICAgICAgICAgMzAgZSAgICAgICAgICAgIDQ3IHY=
ICAgICAgICAxNCBPICAgICAgICAgICAgMzEgZiAgICAgICAgICAgIDQ4IHcgICAgICAgICAocGFkKSA9
ICAgICAgICAxNSBQICAgICAgICAgICAgMzIgZyAgICAgICAgICAgIDQ5IHg=
ICAgICAgICAxNiBRICAgICAgICAgICAgMzMgaCAgICAgICAgICAgIDUwIHk=
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册