phpbase64encode长度,base64_encode
PHP源码阅读笔记三⼗⼋:base64_encode实现
【什么是base64编码】
Base64是⼀种使⽤64基的位置计数法。它使⽤2的最⼤次⽅来代表仅可打印的ASCII 字符。这使它可⽤来作为电⼦邮件的传输编码。在Base64中的变量使⽤字符A-Z、a-z和0-9 ,这样共有62个字符,⽤来作为开始的64个数字,最后两个⽤来作为数字的符号在不同的系统中⽽不同。⼀些如uuencode的其他编码⽅法,和之后binhex的版本使⽤不同的64字符集来代表6个⼆进制数字,但是它们不叫Base64。
【base64编码产⽣的历史原因】
在Email的传送过程中,由于历史原因,Email只被允许传送ASCII字符,即⼀个8位字节的低7位。因此,如果您发送了⼀封带有⾮ASCII字符(即字节的最⾼位是1)的Email通过有”历史问题“的⽹关时就可能会出现问题。⽹关可能会把最⾼位置为0!由于以上原因,产⽣了Base64编码。
【base64_encode的PHP内部实现】
base64_encode是PHP的标准函数,它存在于标准扩展中,在ext/standard/base64.c 210⾏,以标准的
PHP_FUNCTION(base64_encode)实现。如下所⽰代码:
/* {{{ proto string base64_encode(string str)
Encodes string using MIME base64 algorithm */
PHP_FUNCTION(base64_encode)
{
char *str;
unsigned char *result;
int str_len, ret_length;
if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
return;
}
result = php_base64_encode((unsigned char*)str, str_len, &ret_length);
if (result != NULL) {
RETVAL_STRINGL((char*)result, ret_length, 0);
} else {
RETURN_FALSE;
}
}
/* }}} */
第218⾏ 函数的参数输⼊,base64_encode仅有⼀个参数,字符串数据类型;
第221⾏ 调⽤php_base64_encode函数实现base64编码;
第222~226⾏ 返回编码后的值,如果编码成功,返回编码后的字符串,如果失败返回FALSE
[PHP_FUNCTION(base64_encode) -> php_base64_encode()]
PHPAPI unsigned char *php_base64_encode(const unsigned char *str, int length, int *ret_length) /* {{{ */
{
const unsigned char *current = str;
unsigned char *p;
unsigned char *result;
if ((length + 2) < 0 || ((length + 2) / 3) >= (1 << (sizeof(int) * 8 - 2))) {
if (ret_length != NULL) {
*ret_length = 0;
}
return NULL;
}
result = (unsigned char *)safe_emalloc(((length + 2) / 3) * 4, sizeof(char), 1); p = result;
while (length > 2) { /* keep going until we have less than 24 bits */
*p++ = base64_table[current[0] >> 2];
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
*p++ = base64_table[((current[1] & 0x0f) << 2) + (current[2] >> 6)];
*p++ = base64_table[current[2] & 0x3f];
current += 3;
length -= 3; /* we just handle 3 octets of data */
}
/* now deal with the tail end of things */
if (length != 0) {
*p++ = base64_table[current[0] >> 2];
if (length > 1) {
*p++ = base64_table[((current[0] & 0x03) << 4) + (current[1] >> 4)];
*p++ = base64_table[(current[1] & 0x0f) << 2];
*p++ = base64_pad;
} else {
*p++ = base64_table[(current[0] & 0x03) << 4];
*p++ = base64_pad;url编码处理
*p++ = base64_pad;
}
}
if (ret_length != NULL) {
*ret_length = (int)(p - result);
}
*p = '\0';
return result;
}
/* }}} */
第62~67⾏ 输⼊判断,程序的健壮性处理,如果长度⼩于-2,或者长度⼤于2的(机器的int型长度 * 8 – 2)次⽅
第69⾏ 按需分配内存
第72~80⾏ 处理所给字符串的能被3整除的部分,在这⾥需要说明的是Base64编码要求把3个8位字节(3*8=24)转化为4个6位的字节
(4*6=24),之后在6位的前⾯补两个0,形成8位⼀个字节的形式。
第83~94⾏ 处理以3个字节划分后剩余的数据,分成只有⼀个字节,和两个字节的情况,分别在其后⾯添加⼀个或两个base64_pad,在这⾥base64_pad定义为:static const char base64_pad = ‘=’;
最后是添加’\0′,返回结果
【base64的URL应⽤】
Base64编码可⽤于在HTTP环境下传递较长的标识信息。例如,在Java持久化系统Hibernate中,就采⽤了Base64来将⼀个较长的唯⼀标识符(⼀般为128-bit的UUID)编码为⼀个字符串,⽤作HTTP表单和HTTP GET URL中的参数。在其他应⽤程序中,也常常需要把⼆进制数据编码为适合放在URL(包括隐藏表单域)中的形式。此时,采⽤Base64编码不仅⽐较简短,同时也具有不可读性,即所编码的数据不会被⼈⽤⾁眼所直接看到。
然⽽,标准的Base64并不适合直接放在URL⾥传输,因为URL编码器会把标准Base64中的「/」和「+」字符变为形如「%XX」的形式,⽽这些「%」号在存⼊数据库时还需要再进⾏转换,因为ANSI
SQL中已将「%」号⽤作通配符。
为解决此问题,可采⽤⼀种⽤于URL的改进Base64编码,它不在末尾填充’=’号,并将标准Base64中的「+」和「/」分别改成了「*」和「-」,这样就免去了在URL编解码和数据库存储时所要作的转换,避免了编码信息长度在此过程中的增加,并统⼀了数据库、表单等处对象标识符的格式。
另有⼀种⽤于正则表达式的改进Base64变种,它将「+」和「/」改成了「!」和「-」,因为「+」,「*」以及前⾯在IRCu中⽤到的「[」和「]」在正则表达式中都可能具有特殊含义。
此外还有⼀些变种,它们将「+/」改为「_-」或「._」(⽤作编程语⾔中的标识符名称)或「.-」(⽤于XML中的Nmtoken)甚⾄「_:」(⽤于XML中的Name)。
以上部分来源于/zh/Base64
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论