Base64笔记

作者: 阮一峰

日期: 2008年6月23日

1.

天的《MIME笔记》中提到,MIME主要使用两种编码转换方式----Quoted-printable和Base64----将8位的非英语字符转化为7位的ASCII字符。

虽然这样的初衷,是为了满足电子邮件中不能直接使用非ASCII码字符的规定,但是也有其他重要的意义:

a)所有的二进制文件,都可以因此转化为可打印的文本编码,使用文本软件进行编辑;

b)能够对文本进行简单的加密。

2.

首先,简单介绍一下Quoted-printable编码转换方式。它主要用于ACSII文本中夹杂少量非ASCII码字符的情况,不适合于转换纯二进制文件。

它规定将每一个8位的字节,转换为3个字符。

第一个字符是"="号,这是固定不变的。

后面二个字符是二个十六进制数,分别代表了这个字节前四位和后四位的数值。

举例来说,ASCII码中"换页键"(form feed)是12,二进制形式是00001100,写成十六进制就是0C,因此它的编码值为"=0C"。"="号的ASCII值是61,二进制形式是00111101,因为它的编码值是"=3D"。除了可打印的ASCII码以外,所有其他字符都必须用这种方式进行转换。

所有可打印的ASCII码字符(十进制值从33到126)都保持原样不变,"="(十进制值61)除外。

3.

下面,详细介绍Base64的编码转换方式。

所谓Base64,就是说选出64个字符----小写字母a-z、大写字母A-Z、数字0-9、符号"+"、"/"(再加上作为垫字的"=",实际上是65个字符)----作为一个基本字符集。然后,其他所有符号都转换成这个字符集中的字符。

具体来说,转换方式可以分为四步。

第一步,将每三个字节作为一组,一共是24个二进制位。

第二步,将这24个二进制位分为四组,每个组有6个二进制位。

第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节。

第四步,根据下表,得到扩展后的每个字节的对应符号,这就是Base64的编码值。

  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   

  15 P  32 g   49 x

  16 Q  33 h   50 y

因为,Base64将三个字节转化成四个字节,因此Base64编码后的文本,会比原文本大出三分之一左右。

4.

举一个具体的实例,演示英语单词Man如何转成Base64编码。

Text contentMan
ASCII7797110
Bit pattern010011010110000101101110
Index1922546
Base64-EncodedTWFu

第一步,"M"、"a"、"n"的ASCII值分别是77、97、110,对应的二进制值是01001101、01100001、01101110,将它们连成一个24位的二进制字符串010011010110000101101110。

第二步,将这个24位的二进制字符串分成4组,每组6个二进制位:010011、010110、000101、101110。

第三步,在每组前面加两个00,扩展成32个二进制位,即四个字节:00010011、00010110、00000101、00101110。它们的十进制值分别是19、22、5、46。

第四步,根据上表,得到每个值对应Base64编码,即T、W、F、u。

因此,Man的Base64编码就是TWFu。

5.

如果字节数不足三,则这样处理:

a)二个字节的情况:将这二个字节的一共16个二进制位,按照上面的规则,转成三组,最后一组除了前面加两个0以外,后面也要加两个0。这样得到一个三位的Base64编码,再在末尾补上一个"="号。

比如,"Ma"这个字符串是两个字节,可以转化成三组00010011、00010110、00010000以后,对应Base64值分别为T、W、E,再补上一个"="号,因此"Ma"的Base64编码就是TWE=。

b)一个字节的情况:将这一个字节的8个二进制位,按照上面的规则转成二组,最后一组除了前面加二个0以外,后面再加4个0。这样得到一个二位的Base64编码,再在末尾补上两个"="号。

比如,"M"这个字母是一个字节,可以转化为二组00010011、00010000,对应的Base64值分别为T、Q,再补上二个"="号,因此"M"的Base64编码就是TQ==。

6.

再举一个中文的例子,汉字"严"如何转化成Base64编码?

这里需要注意,汉字本身可以有多种编码,比如gb2312、utf-8、gbk等等,每一种编码的Base64对应值都不一样。下面的例子以utf-8为例。

首先,"严"的utf-8编码为E4B8A5,写成二进制就是三字节的"11100100 10111000 10100101"。将这个24位的二进制字符串,按照第3节中的规则,转换成四组一共32位的二进制值"00111001 00001011 00100010 00100101",相应的十进制数为57、11、34、37,它们对应的Base64值就为5、L、i、l。

所以,汉字"严"(utf-8编码)的Base64值就是5Lil。

7.

在PHP语言中,有一对专门的函数用于Base64转换:base64_encode()用于编码、base64_decode()用于解码。

这对函数的特点是,它们不管输入文本的编码是什么,都会按照规则进行Base64编码。因此,如果你想得到utf-8编码下的Base64对应值,你就必须自己保证,输入的文本是utf-8编码的。

8.

这一节介绍如何用Javascript语言进行Base64编码。

首先,假定网页的编码是utf-8,我们希望对于同样的字符串,用PHP和Javascript可以得到同样的Base64编码。

这里就会产生一个问题。因为Javascript内部的字符串,都以utf-16的形式进行保存,因此编码的时候,我们首先必须将utf-8的值转成utf-16再编码,解码的时候,则是解码后还需要将utf-16的值转回成utf-8。

网上已经有人写好了现成的Javascript函数:


/* utf.js - UTF-8 <=> UTF-16 convertion
*
* Copyright (C) 1999 Masanao Izumo <[email protected]>
* Version: 1.0
* LastModified: Dec 25 1999
* This library is free. You can redistribute it and/or modify it.
*/

/*
* Interfaces:
* utf8 = utf16to8(utf16);
* utf16 = utf8to16(utf8);
*/

function utf16to8(str) {
var out, i, len, c;

out = "";
len = str.length;
for(i = 0; i < len; i++) {
c = str.charCodeAt(i);
if ((c >= 0x0001) && (c <= 0x007F)) {
out += str.charAt(i);
} else if (c > 0x07FF) {
out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
out += String.fromCharCode(0x80 | ((c >> 6) & 0x3F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c >> 6) & 0x1F));
out += String.fromCharCode(0x80 | ((c >> 0) & 0x3F));
}
}
return out;
}

function utf8to16(str) {
var out, i, len, c;
var char2, char3;

out = "";
len = str.length;
i = 0;
while(i < len) {
c = str.charCodeAt(i++);
switch(c >> 4)
{
case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7:
// 0xxxxxxx
out += str.charAt(i-1);
break;
case 12: case 13:
// 110x xxxx 10xx xxxx
char2 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x1F) << 6) | (char2 & 0x3F));
break;
case 14:
// 1110 xxxx 10xx xxxx 10xx xxxx
char2 = str.charCodeAt(i++);
char3 = str.charCodeAt(i++);
out += String.fromCharCode(((c & 0x0F) << 12) |
((char2 & 0x3F) << 6) |
((char3 & 0x3F) << 0));
break;
}
}

return out;
}

上面的这段代码中定义了两个函数,utf16to8()用于将utf-16转成utf-8,utf8to16用于将utf-8转成utf-16。

下面才是真正用于base64编码的函数。

/* Copyright (C) 1999 Masanao Izumo <[email protected]>
* Version: 1.0
* LastModified: Dec 25 1999
* This library is free. You can redistribute it and/or modify it.
*/

/*
* Interfaces:
* b64 = base64encode(data);
* data = base64decode(b64);
*/


var base64EncodeChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
var base64DecodeChars = new Array(
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
-1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1);

function base64encode(str) {
var out, i, len;
var c1, c2, c3;

len = str.length;
i = 0;
out = "";
while(i < len) {
c1 = str.charCodeAt(i++) & 0xff;
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt((c1 & 0x3) << 4);
out += "==";
break;
}
c2 = str.charCodeAt(i++);
if(i == len)
{
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt((c2 & 0xF) << 2);
out += "=";
break;
}
c3 = str.charCodeAt(i++);
out += base64EncodeChars.charAt(c1 >> 2);
out += base64EncodeChars.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));
out += base64EncodeChars.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6));
out += base64EncodeChars.charAt(c3 & 0x3F);
}
return out;
}

function base64decode(str) {
var c1, c2, c3, c4;
var i, len, out;

len = str.length;
i = 0;
out = "";
while(i < len) {
/* c1 */
do {
c1 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
} while(i < len && c1 == -1);
if(c1 == -1)
break;

/* c2 */
do {
c2 = base64DecodeChars[str.charCodeAt(i++) & 0xff];
} while(i < len && c2 == -1);
if(c2 == -1)
break;

out += String.fromCharCode((c1 << 2) | ((c2 & 0x30) >> 4));

/* c3 */
do {
c3 = str.charCodeAt(i++) & 0xff;
if(c3 == 61)
return out;
c3 = base64DecodeChars[c3];
} while(i < len && c3 == -1);
if(c3 == -1)
break;

out += String.fromCharCode(((c2 & 0XF) << 4) | ((c3 & 0x3C) >> 2));

/* c4 */
do {
c4 = str.charCodeAt(i++) & 0xff;
if(c4 == 61)
return out;
c4 = base64DecodeChars[c4];
} while(i < len && c4 == -1);
if(c4 == -1)
break;
out += String.fromCharCode(((c3 & 0x03) << 6) | c4);
}
return out;
}

上面代码中的base64encode()用于编码,base64decode()用于解码。

因此,对utf-8字符进行编码要这样写:

sEncoded=base64encode(utf16to8(str));

然后,解码要这样写:

sDecoded=utf8to16(base64decode(sEncoded));

(完)

留言(35条)

前几天发现一个模板用了base64来隐藏代码。原来是这样的原理。

很多文本混杂大量等号,大小写字母,一看就知道是base64。
我主要用它在传输有unicode的文本时起一点作用,加密的用处不大了,所有人都知道电子邮件就是base64

唔 不太会说啥~~这个应该有用 请收下 因为是本人手打如有错误请见谅 祝网站越来越好
意大利童话
卡尔维诺选

一百四十一
火鸡
以前有一中国王和一个王后,王后在生一个男孩时死了。男孩活了下来.与一十年龄稍大的姐姐在一起。国王为此悲痛欲绝,整天哭泣。就过样.一年之后他也去世了。
国王有个兄弟,在临终前他把自己的两个孩子托付给了他。叔叔答应了.并发了誓。但是国王刚死,他就想自己加冕当国王,统治全国。他是个暴君,把侄子和侄女关在一个地牢里。当侄子十岁时.每天都把他派到田里让他监督人们干话。
男孩子每天都在过着这种生恬,他长大了,到十七岁时,他还不知道他和姐姐是王室的后代.他更不知道现在的国王是他们的叔叔.还“为国王只是出于怜悯才收留他们姐弟的。
圣诞节快到了。有个老妇人以养鹅和火鸡为生.她知道这两个孩子所处的条件,很同情他们。她自语道:“明天就是圣诞前夜了,这两个可怜的孩子孤孤单单,无依无靠,要是他们去世的父亲还活着的话,他们就会有丰盛的宴席,就会享受到无穷的乐趣。
已经去世的老国王本可以为他们做一切事情的!所有的人都在准备欢度圣诞节,就连我这个养鹅的老女人也不例外,那两个孩子一无所有!现在我要送给他们一只火鸡作为礼物,让他们能欢度圣诞节!怎么才能给他们呢,我无法通过大门,因为有卫兵把守…对.我应该到窗户那里去喊那个姑娘。”
就在圣诞节前一天的早晨,老妇人起床后拿了一只最肥的火鸡在窗下叫起来:“小姐,小姐!今天是圣诞节前夜,我想把这只火鸡作为礼物送给你们,您和您的弟弟一起吃它吧,为我的健康干杯!”
姑娘把头伸出窗外,说:谢谢您好心的婆婆。可我拿什么东西报答您呢?我一无所有......”她本不想收下这只火鸡,但是在这个好心的老妇人再三请求下,还是收下了。
节日那天早晨,弟弟并没有去田里而是到国王那里交账。姐姐等着弟弟回家,她把火鸡锁到了一间黑屋子以免让人看见。那只火鸡独自呆在屋里,就用爪子在地上又抓又挖,直到挖出一个活门板。傍晚弟弟带着一些吃的回来了,姐弟二人坐在餐桌吃饭的时候,姐姐说:“弟弟,你知道吗?今天早上一个好心的老婆婆送给我一只火鸡作为礼物。”
“你把它放在哪里了?”弟弟问。
“我把它藏在了一件黑屋子里。我现在就去给它喂食。”
弟弟很累,吃晚饭就去睡觉了。姐姐拿着蜡烛去看那只火鸡。她看见了被火鸡挖出的洞,也看见了那个活门板,“看看火鸡发现了什么!”她打开木板,见里面有台阶。“我下去看看。”姑娘说着走下台阶。她看见一套国王的盔甲:头盔、 佩剑、 胸甲,就只缺少王冠。“这是谁的呢?”姑娘自言自语道。“管它是谁的。”说着她就把这些东西拿到了自己屋里。
“你不知道吗?”姐姐回答说,“那只火鸡挖出了个活门板,地下有台阶。我顺台阶走到地下室发现了这些东西。”
“但是这是国王的衣服呀!”弟弟说。
“没错!多漂亮的衣服呀!快穿上,我的弟弟,我想看看你穿上这身衣服是什么样子。快,快穿上它。”姐姐帮弟弟穿戴好,高兴地拍着手。
这时候,他们听见一阵阵喇叭声和锣鼓声:今天是圣诞节前夜,乐师们正在王宫的窗下演奏呢。
姑娘打开窗,聚集在广场上的所有人都看见了戴着头盔、 配着剑、 穿着胸甲的男孩。
人们高呼起来:“这是我们的国王!这是我们的国王!”
听到这些呼声,王宫的卫兵开始戒备起来,从人群当中又发出了一阵震耳欲聋的呼喊声,宫廷里的人也开始乱喊起来:“怎么会事?怎么回事?”
外面的人看到王宫里一片混乱,开始叫喊:“打倒!”说是:“万岁!”人们从城里的四面八方涌向广场,喊声越来越嘹亮,人们越聚越多。
国王吓得脸色苍白,顺着台阶走出宫殿,想对高呼的人群讲几句话,可是人们恨死了他的暴政,都希望早些结束他的统治。人们用石头砸,他用拳头揍他,最后把他打死了,这是他罪有应得。人们在欢呼声和爆竹声中,摘下王冠给他的侄子戴上。
当上国王后年轻人公正的治理国家,所有人都幸福的生活着,大家都很爱戴他。所有的穷人都到王宫来,他亲自给予赈济物。穷人们从各地前来,从他手中接过赈济物。这样一直过了许多个星期五,直到他也几乎感到厌倦了。一次,国王要离开时,见穷人中有一个瞎眼的老妇人,身边是一个大约十二岁的姑娘扶着她,小姑娘用招人同情的声调说:“国王陛下,请您可怜可怜这位瞎眼的老婆婆吧,上帝会报答您的。”
国王一边给老人发救济品,一边看这个姑娘,他发现这个姑娘非常美丽,于是说:“善良的姑娘啊,你们每个星期五都要来呀,来时离其他人远一些,不要与其他穷人混在一起,这样我才能一眼就看见你们。”
老妇人和姑娘走了,一边走一边为国王祝福。国王感到非常忧伤,他觉得等到下个星期五再看见她们像是要过上百年。终于等到了星期五,国王朝人群一眼望去在队尾看见她们,她们按照国王的吩咐远离人群,国王向她们招招手,让她们过来,给了她们比别人更多的钱,之后对姑娘说:“扔掉你身上的破衣服,去做一身新衣服,下星期五穿上新装来见我。”
到了下个星期五,姑娘穿着一身棉布衣和一双新鞋来了,国王又给了他更多的钱,就这样,每个星期她都来,穿的衣服越来越好。后来她身上穿着一件薄纱衣,打扮的像朵娇艳的玫瑰花。
国王已经爱上了这个姑娘,在家里总是显得很忧伤。姐姐注意到了,就问他:“弟弟,你怎么啦?”
他说:“没什么......我头疼......”然而在姐姐的一再追问下,最后他再也无法掩饰自己的感情,说道:“我爱上了一个贫穷的姑娘,我想娶她为妻。”
国王本以为姐姐绝不会同意他和一个贫穷的姑娘结婚,可是他的姐姐心地善良,很爱弟弟,并且她曾经也很贫穷她只对他说自己想见那姑娘。
又到了星期五,姐姐和弟弟一同去发放救济品,那个漂亮的乞讨姑娘就在第一个。见她这么美丽,姐姐对国王说:“按你的心愿办吧。”这样国王和姑娘结了婚。
举行婚礼那天。国王对姐姐说:“虽然我现在结婚了,但我们两个的事还和从前一样,由你来做主。”
然而新娘自从穷人成为王后之后就目中无人起来。她妒忌国王的姐姐,因她是当家的,掌管所有地方的钥匙。慢慢地,他开始挑拨自己的丈夫和姐姐之间的关系。她让丈夫收回钥匙,还强迫他无缘无故地责骂姐姐,可怜的姐姐变的益加善良。可是新娘对国王讲了许多话,最后国王对她说:“我的妻子,你到底要我干什么呢?”
她说:“晚上的时候,把她带到树林里杀了,为了确定她被杀死了,要把她的心、双手和有血印的衬衣带回来。
事情便这样做了半夜,可怜的姐姐发现先自己被叫醒,并被两个杀手抓了起来。“你们要干什么?”
他们把姑娘放在马车上,带到了乡下。当到达树林时两个杀手商量道:“现在我们就要毫无理由地把她杀掉,可她从没做过伤害过我们的事情,可怜的姑娘!”
“我绝不会杀她的。”另一个杀手说,“你杀她吧。”
“那么我们该怎么办呢?为了能拿着她的心、双手和沾满血迹的衬衣向国王交差,我们不得不杀死她。“
就在这时,他们听见一阵羊叫声:是一只在夜间迷了路留在林中的小羊羔。她们抓住小羊对公主说:“脱下您的衬衣,现在我们要杀死这只小羊羔,取出它的心。但是很对不起,我们必须砍下您的双手:这是命令。请您忍耐一下吧!”就这样,他们砍下了公主的双手。带着小羊羔的心何用衬衣包着的手,他们回去复命了。
公主留在那里,她的手腕上涌着鲜血。国王看到姐姐的那些残留物忍不住泪流满面,说道:“我的姐姐呀,当初在我的婚礼上你是那么高兴,可现在我的妻子害死了你呀!”他回忆起过去的时光,非常后悔自己做出这种事,他哭喊着:“我的姐姐,我的姐姐呀!”
正当国王悲痛欲绝时,他的姐姐还躺在树林中,手腕还滴着血。就在这时,有个英国勋爵乘一辆小马车经过树林。他听到呻吟声,发现了那个姑娘,问她是被谁伤害的。姑娘回答是被野兽咬断了她的手。勋爵想起马车上有一些布,便拿来给她包上止血,然后请姑娘上了马车,把她带走了。这个英国勋爵已经结婚,但膝下无子。可以想象姑娘在勋爵家过的很幸福,为了不使她一直这样没有双手,英国勋爵还用蜡为她做了一双假手。
伴随着不幸的遭遇,公主长到了二十岁,长得像玫瑰一般美丽鲜艳。她站在阳台上,正好有位外国的国王从路上
经过,看见了她并喜欢上了这个姑娘。他去向英国勋爵求婚,勋爵同意了这门亲事,但他诚实的告诉国王,姑娘的双手是蜡做的。国王说他并不在乎,就这样他娶了姑娘并把她带回王宫。
国王离家的时候,王后生了一男一女两个孩子。可是那些大臣不能忍受被一个女人统治,在说谁也不知道这女人是何处来的,于是他们想利用这个机会摆脱她。
他们给国王写了一封信,告诉他王后生了两只小狗 。他们正等待国王发布命令处置王后。
国王难过极了,回信说等他回去看过之后,再决定如何处置。但是大臣们要不惜一切代价摆脱王后的统治,他们在半夜将王后弄醒,把一个大包斜挎在她的肩上,然后把两个小孩子放进背包里,一边一个。最后再把她丢在荒无人烟的海滩上 。
可怜的王后哭起来。她孤单一个人,又渴又饿,只有两只断臂,真是走投无路。她找到一口井,想低头喝口水。刚弯下腰,一个孩子从背包里滑出来,掉到水里沉下去了。你可以想象她是多么悲伤:因为她没有手,无法把孩子捞起来。
正在这时,在她面前出现了一个英俊的老人,说道:

“把你的断臂伸进水里
你就会重新有手有孩子。”

王后把一条断臂伸进水里,觉得长出了手,她马上抓住孩子把 他捞了上来。她这样一动,另一个孩子又从背包里滑出来沉入水里。
老人又说道:

“把你的断臂伸进水里
你就会重新有手有孩子。”

她的另一只手也长了出来,她把孩子捞了上来。有了手,她就能给两个孩子喂奶了。好心的老人带她来到一个山顶,那里建有一间漂亮的房子。他让姑娘进屋,对她说道:“住在这里,你什么都不会缺。我不会抛下你不管的。”
我们暂且不说王后,回头讲讲她的丈夫--国王。战争结束后他回到家,由于找不到妻子感到万分悲痛。他问大臣,可大臣们都说她夜里带着她生下的两只小狗出走了,此外一无所知。国王找不到妻子无法安心,于是到乡下四处寻找。

与此同时,王后的弟弟自从后悔杀害了无辜的姐姐就再不出门。任胡子长的一直拖到膝盖。他把妻子关进了地牢,因为是她误导了他的公正。大臣们劝说了很久,一天他们说服了国王,同意出去打猎活动一下筋骨。当他到了乡下,依然心事重重,心神不定,结果和大臣们走散了,迷了路,突然天下起大雨来国王只好在一棵栎树下避雨。
另一个国王也就是他姐姐的丈夫,正在寻找自己的妻子,刚巧从那片树林经过 ,也是在这棵栎树下避雨。这样,他们相遇了。尽管他们都是国王,但他们以前从未谋面。他们看见一点亮光,于是便冒雨向亮光走去,这亮光正是从那个好心的老人屋里射出来的,也就是他们中一个人的姐姐,另一个人的妻子住的地方。
他们敲了敲门,老人开了门并让他们进屋避雨。他们走进屋,王后就住在屋里,她认出了他们,但他们没认出她。
“天在下雨。”老人说,“这两位先生想在这里避雨并请求我们招待。”
“非常荣幸。”她说,“我正准备为我的孩子做饭呢。”
“那么我们一起吃饭吧。”老人说。
快要吃完饭,老人对两个孩子说道:“亲爱的孩子们,现在你们给我们将个美好的故事吧,我们都很乐意听。”
小女孩迫不及待地讲起来。她说讲得是她妈妈的故事,从她被两个杀手抓到树林开始,一直讲到结婚。听了这个故事,弟弟心里暗想:这就是我的姐姐。 小女孩讲完了,小男孩开始讲。从她得妈妈嫁给一位国王开始,讲到善良的老人把他们母子三人带到山上,并在这间屋里住下。国王听完这个故事心想:这样说来这位妇人就是我的妻子,那么着可爱的孩子不就是我的儿女吗?为什么大臣们告诉说她生了两条狗呢?
孩子们讲完后,老人说:“先生们,这正是你们的故事。”两个两个国王拥抱了少妇,一个请求她原谅,另一个还眼含热泪的亲吻了孩子们。看到此情此景,那个老人,也就是圣朱塞佩,非常高兴;他的手杖开满了鲜花,这是行善的标志。“现在我已经尽到我的责任。” 他说,“祝福你们。”说完便消失了。

(卡拉布里亚地区)


思考:
觉得真是成人的童话 也许是见心见性吧 突然觉得跟现实 如出一辙

引用寂寞王子的发言:

唔 不太会说啥~~这个应该有用 请收下 因为是本人手打如有错误请见谅 祝网站越来越好

非常感谢你的输入,已经加入网站了。

http://www.ruanyifeng.com/calvino/2006/10/the_turkey_hen.html

我正在学习如何使用base64传输图片,您的文章给了我很大帮助,谢谢

你写的教程太容易读懂了.真是不错.谢了

比如,“Ma”这个字符串是两个字节,可以转化成三组00010011、00010110、00010000以后

这里的00010000应该为0000100...

写的很好懂。多谢!

5.中有点小错误:
“可以转化成三组00010011、00010110、00010000以后”,这句话中,最后一组应当是 00000100

引用风海迷沙的发言:

很多文本混杂大量等号,大小写字母,一看就知道是base64。
我主要用它在传输有unicode的文本时起一点作用,加密的用处不大了,所有人都知道电子邮件就是base64

那就看你怎么加密了!

最下面的算法看不懂,网上看到的utf-16也不怎么清楚

简单易懂啊.
具体的把算法体现到代码级别就看不下去. 数理这块不行.

唔 不太会说啥~~这个应该有用 请收下 因为是本人手打如有错误请见谅 祝网站越来越好
意大利童话
卡尔维诺选
一百四十一
火鸡
以前有一中国王和一个王后,王后在生一个男孩时死了。男孩活了下来.与一十年龄稍大的姐姐在一起。国王为此悲痛欲绝,整天哭泣。就过样.一年之后他也去世了。
国王有个兄弟,在临终前他把自己的两个孩子托付给了他。叔叔答应了.并发了誓。但是国王刚死,他就想自己加冕当国王,统治全国。他是个暴君,把侄子和侄女关在一个地牢里。当侄子十岁时.每天都把他派到田里让他监督人们干话。
男孩子每天都在过着这种生恬,他长大了,到十七岁时,他还不知道他和姐姐是王室的后代.他更不知道现在的国王是他们的叔叔.还“为国王只是出于怜悯才收留他们姐弟的。
圣诞节快到了。有个老妇人以养鹅和火鸡为生.她知道这两个孩子所处的条件,很同情他们。她自语道:“明天就是圣诞前夜了,这两个可怜的孩子孤孤单单,无依无靠,要是他们去世的父亲还活着的话,他们就会有丰盛的宴席,就会享受到无穷的乐趣。
已经去世的老国王本可以为他们做一切事情的!所有的人都在准备欢度圣诞节,就连我这个养鹅的老女人也不例外,那两个孩子一无所有!现在我要送给他们一只火鸡作为礼物,让他们能欢度圣诞节!怎么才能给他们呢,我无法通过大门,因为有卫兵把守…对.我应该到窗户那里去喊那个姑娘。”
就在圣诞节前一天的早晨,老妇人起床后拿了一只最肥的火鸡在窗下叫起来:“小姐,小姐!今天是圣诞节前夜,我想把这只火鸡作为礼物送给你们,您和您的弟弟一起吃它吧,为我的健康干杯!”
姑娘把头伸出窗外,说:谢谢您好心的婆婆。可我拿什么东西报答您呢?我一无所有......”她本不想收下这只火鸡,但是在这个好心的老妇人再三请求下,还是收下了。
节日那天早晨,弟弟并没有去田里而是到国王那里交账。姐姐等着弟弟回家,她把火鸡锁到了一间黑屋子以免让人看见。那只火鸡独自呆在屋里,就用爪子在地上又抓又挖,直到挖出一个活门板。傍晚弟弟带着一些吃的回来了,姐弟二人坐在餐桌吃饭的时候,姐姐说:“弟弟,你知道吗?今天早上一个好心的老婆婆送给我一只火鸡作为礼物。”
“你把它放在哪里了?”弟弟问。
“我把它藏在了一件黑屋子里。我现在就去给它喂食。”
弟弟很

写的真好!

请问图片如何进行编码呢?

感谢,这篇文章让我彻底懂了,很简单。

楼主,在Ma那个例子里面,转换成的三组应该是00010011、00010110、00000100(文章中最后一个写成了00010000,错了)

“比如,"Ma"这个字符串是两个字节,可以转化成三组00010011、00010110、00010000以后,对应Base64值分别为T、W、E,再补上一个"="号,因此"Ma"的Base64编码就是TWE=。”

这最后一个应该是“00000100”吧?

引用涛涛的发言:

“比如,"Ma"这个字符串是两个字节,可以转化成三组00010011、00010110、00010000以后,对应Base64值分别为T、W、E,再补上一个"="号,因此"Ma"的Base64编码就是TWE=。”

这最后一个应该是“00000100”吧?

博主是写错了,因为00010000转为十进制是16,对应base64码表是Q,00000100转为十进制是4,对应base64码表是E。

虽然不怎么来,不过每次被搜索引擎带到这里总有收获,博主文章总是通俗易懂,

说一些相关的. HTML 中的 data URL.

一个二进制的文件(通常是图片)可以被转为 base64 编码, 所以极小的文件可以被直接放在 HTML 中使用. 为什么其他文件不可以? 1. 各尽其职, 图片本不应被放在 HTML 中. 2. 体积增大, 二进制被转为 base64 后体积会膨胀 30% 以上.

http://stackoverflow.com/questions/5258057/should-i-embed-images-as-data-base64-in-css-or-html

我就是想知道在HTML 中,使用img src="",到底有什么用处呀!(并不是base64 的实现原理/技术细节)

引用nana的发言:

楼主,在Ma那个例子里面,转换成的三组应该是00010011、00010110、00000100(文章中最后一个写成了00010000,错了)

嗯,怪不得,我看了几遍都觉得不太对

首先,假定网页的编码是utf-8,我们希望对于同样的字符串,用PHP和Javascript可以得到同样的Base64编码。
这里就会产生一个问题。因为Javascript内部的字符串,都以utf-16的形式进行保存,因此编码的时候,我们首先必须将utf-8的值转成utf-16再编码,解码的时候,则是解码后还需要将utf-16的值转回成utf-8。

这个写错了吧,应该是 因此编码的时候,我们首先必须将utf-16的值转成utf-8再编码,解码的时候,则是解码后还需要将utf-8的值转回成utf-16。
这样才合乎逻辑,并且和你后面的代码对应:

因此,对utf-8字符进行编码要这样写:
sEncoded=base64encode(utf16to8(str));
然后,解码要这样写:
sDecoded=utf8to16(base64decode(sEncoded));

2018年看阮老师这篇还是比较容易懂的

若阮老师能解析下这几个问题会不错:
- 为什么常用的是 base64,而非 base16、base32、base63、base128 等?
- base64 里为什么需要每个 6 位二进制需要前面补两位 00?
- 最后的补全字符 `=` 的好处是什么?

牛人啊,哪都有你

base64转码介绍中,二个字符Ma转为四个8位2进制时,第三个位为00000100,您在文中写错为00010000

字母转成二进制后,把它8位8位地二进制拼装起来,然后从前往后,6位6位地分,这个从前往后顺序是不是应该说明一下,不然做Ma的转换时,有点懵

前面加两个零,后面加两个零。。。
是错了吧!

多谢前辈的讲解,一下看懂了~ 感谢万分

比如,"Ma"这个字符串是两个字节,可以转化成三组00010011、00010110、00010000

阮老师,这个按照之前的推算,我的理解好像是写错了,应该是00010011、00010110、00000100

引用Viky的发言:

2018年看阮老师这篇还是比较容易懂的

若阮老师能解析下这几个问题会不错:
- 为什么常用的是 base64,而非 base16、base32、base63、base128 等?
- base64 里为什么需要每个 6 位二进制需要前面补两位 00?
- 最后的补全字符 `=` 的好处是什么?

base64命名是因为用到的编码字典表用了64个字符,如果是base16,编码字符会不够,导致生成的编码很长,如果是128(ASCII),其中很多的字符都是控制字符,无法输出,造成编码空间的浪费

每个6位二进制前面补全00是为了方便分割,可以参照ASCII字符,ASCII字符的二进制长度也就7位,但是通常都在前面补上0,刚好凑成8位1B,补上0对计算没有影响

最后补全字符是“=”只是为了统一规范吧,没什么特别的意义

讲得很明白,第一次知道不用注册就可以评论

6比特前补00,这个操作维基百科都没写。一开始看的时候还怀疑了一下。其实补和不补都没有什么影响。但是8为符合计算机

有笔误
比如,"Ma"这个字符串是两个字节,可以转化成三组00010011、00010110、00000100

我要发表看法

«-必填

«-必填,不公开

«-我信任你,不会填写广告链接