php utf-8编码格式的一些知识

在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的博客文章

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值