在UTF-8的二进制编辑格式中,UTF-8的字节是可变的。可以占用一字节也可以占用二字节,三字节,四字节等
ASCII 码的:0-127 在UTF-8中也是只占一个字节的内容,和ASCII一样,没有变化,比如:UTF-8 中 a 的二进制就是:1100001,7位,因为ASCII 没有负数位,所以,只用了后7位,第8位是用0代替,a完整的二进制码就是:01100001
汉字在UTF-8中 基本是占用3字节,也有4字节的不常用字符。
例:汉字 “一” 的二进制码是:11100100 10111000 10000000
使用三个字节。第一个字节的,前三个‘1’ 表示,这个汉字使用的字节数量,几个‘1’表示用几个字节,第二个字节和第三个字节的‘10’开头都是固定的格式。
一个两字节的汉字的二进制编码格式就是:110xxxxx 10xxxxxx (‘x‘占11位)
一个三字节的汉字的二进制编码格式就是:1110xxxx 10xxxxxx 10xxxxxx (‘x‘占16位)
一个四字节的汉字的二进制编码格式就是:11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (‘x‘占21位)
'x' 就是我们要使用的值,将所有的'x'连成一个二进制字符串,
如例“一”的二进制 11100100 10111000 10000000 取出其中我们需要的 01001110 00000000,将其换算成十六进制得:4E00,
我们只要输出 一 就可以显示汉字一了。
关于PHP中文截取无乱码的办法,大家也可以参照一下这种处理方法,或 系统自带的mb_substr()
将汉字转成二进制的方法:
//汉字是三个字节,所以strlen($n) 等于 3,这里会分三次,取出这三个字节里的值,用回ord读取单字节返十进制,再用 decbin 把十进制转成二进制。
//此处存在个问题就是,前提我们得知道,这个字是个UTF-8格式的汉字才可以, 如果是GB2312,虽然也可以用这个办法取得正确的二进制串,但如果用上面所说的组合格式及办法就会出现字不对的情况。GB2312是使用二字节的。而且也没有1110xxxx 这类的格式。
//如果是读取一个文件,可以读取文件的头三个字节, UTF-8的文件要求前三个字节是:EF、BB、BF,其后才是正常的文件格式。
$n = '汉';
for($i = 0; $i < strlen($n); ++$i)
{
decbin(ord($n[$i]));
}
UTF-8
这是汉字转成二进制串的函数,
public function utf2($n)
{
//URL提交过来的参数进行反URL编码
$n = urldecode($n);
//生成的二进制串 @string
$bin_str = '';
//生成二进制串
for($i = 0; $i < strlen($n); ++$i)
{
$_str = decbin(ord($n[$i]));
//echo s$_str;
if(strlen($_str) == 7)
{
$bin_str .= '0'.$_str;
}
else
{
$bin_str .= $_str;
}
}
//分解成每个字的二进制串
while($bin_str)
{
$one = 0;
$_bin_str = substr($bin_str, 0, 6);
for($i = 0; $i < 6; ++$i)
{
if($_bin_str[$i] != 1)
{
break;
}
++$one;
}
$_bin_str = substr($bin_str, 0, ($one == 0)?(8):($one * 8));
$bin_str = substr($bin_str, ($one == 0)?(8):($one * 8));
echo $this->toutf($_bin_str);
}
}
给一节 参数为二进制串 生成汉字的 函数,$_bin_str 就是二进制串了,基本上我们使用的汉字都是24里面。16 和 32 基本是用不上的啦,所以,我16 和 32 也没有测试过,是否正确还需测试。
正则函数,返回正则格式里三个括号里的内容,$1 $2 $3 分别对应三个括号,关于这个函数,更详细的自已查手册吧。
preg_replace('/1110([\d]{4})10([\d]{6})10([\d]{6})/', '$1$2$3', $_bin_str);
private function toutf($_bin_str)
{
switch(strlen($_bin_str))
{
case 8:
{
//echo '8<br />';
return '&#x'.dechex(bindec($_bin_str)).';';
break;
}
case 16:
{
//echo '16<br />';
$dec = preg_replace('/110([\d]{5})10([\d]{6})/', '$1$2', $_bin_str);
echo '&#x'.dechex(bindec($dec)).';';
break;
}
case 24:
{
//echo '24<br />';
$dec = preg_replace('/1110([\d]{4})10([\d]{6})10([\d]{6})/', '$1$2$3', $_bin_str);
return '&#x'.dechex(bindec($dec)).';';
break;
}
case 32:
{
//echo '32<br />';
$dec = preg_replace('/11110([\d]{3})10([\d]{6})10([\d]{6})10([\d]{6})/', '$1$2$3$4', $_bin_str);
echo '&#x'.dechex(bindec($dec)).';';
break;
}
}
}
关于UTF-8的一些资料可以详细查看 维基百科 “中日韩越统一表意文字” 或 “基本多平面文字” 及 “sandyen的博客文章”