<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>程默的博客</title>
	<atom:link href="http://blog.chacuo.net/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.chacuo.net</link>
	<description>web原理、web架构、web安全、web性能、服务器性能、服务器架构、服务器安全;你不能预知明天，但你可以利用今天。你不能样样顺利，但你可以事事尽力!</description>
	<lastBuildDate>Mon, 31 Aug 2020 15:33:40 +0000</lastBuildDate>
	<language>zh-CN</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>http 接口调试在线工具 24log dump http request raw</title>
		<link>http://blog.chacuo.net/1436.html</link>
		<comments>http://blog.chacuo.net/1436.html#comments</comments>
		<pubDate>Mon, 31 Aug 2020 15:17:47 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[其它]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=1436</guid>
		<description><![CDATA[很久没有写东西了，一直要开始，一直没有动手，在线工具24mail推出有尽8个年头了，chacuo.net工具更 [...]]]></description>
				<content:encoded><![CDATA[<p>很久没有写东西了，一直要开始，一直没有动手，在线工具24mail推出有尽8个年头了，chacuo.net工具更新很少，期间经常收到一些朋友询问与咨询，对站点一些工具给与肯定，本身作为码农的我，线上很多工具都是来自于工作需求，想想码农的我需要使用，大家肯定也需要的。</p>
<p>啰嗦了，今天介绍一款 最新工具 24log.chacuo.net 在线dump http request raw工具。先说说使用场景把， chrome 自带的强大http 请求调试抓包，想必大家经常使用，但是作为移动端，接口开发，app开发，我们也经常会接触到 api 请求，以为接口进行编码，加密，对接时候经常出问题。有时候我们想知道，自己发送服务端接口原始数据是什么，因此我们需要dump出 自己request 请求，一番调试，修改代码，很是好烦时间，有没有一款工具，能够在线查看到我日志，以及 服务端返回的内容呢，24log.chacuo.net 就可以解决这个问题。该工具有2个功能，我们看看第一个常用功能。</p>
<p><a href="http://24log.chacuo.net/my" target="_blank">24log.chacuo.net/my</a> ，它是一个开放接口，所有用户都可以调用，我们访问一下试试看</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2020/08/image.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2020/08/image_thumb.png" width="465" height="526"></a> </p>
<p>直接打印出，我请求该地址 ， request 请求， 通过该地址，以下2个方面很方便：</p>
<p>1、测试 浏览器 发送 请求 header 头，只需要 通过该浏览器，访问 <a href="http://24log.chacuo.net/my" target="_blank">24log.chacuo.net/my</a> 地址即可，看到请求参数， user-agent</p>
<p>2、公共地址 支持常见的&#8217;OPTIONS&#8217;, &#8216;GET&#8217;, &#8216;HEAD&#8217;, &#8216;POST&#8217;, &#8216;PUT&#8217;, &#8216;DELETE&#8217;, &#8216;TRACE&#8217; 协议，我们看看给发一个 formdata 表单请求</p>
<blockquote><p>curl &#8217;24log.chacuo.net/my&#8217;&nbsp; -F &#8216;test=测试一下&#8217; -F &#8216;who=我是谁&#8217;</p>
<p>&nbsp;</p>
<p>POST /my HTTP/1.1<br />Host: 24log.chacuo.net<br />Connection: Keep-Alive<br />Content-Length: 252<br />Accept-Encoding: gzip<br />User-Agent: curl/7.29.0<br />Accept: */*<br />Content-Type: multipart/form-data; boundary=&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;-7169b4ab667a
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;7169b4ab667a<br />Content-Disposition: form-data; name=&#8221;test&#8221;
<p>测试一下<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;7169b4ab667a<br />Content-Disposition: form-data; name=&#8221;who&#8221;
<p>我是谁<br />&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;7169b4ab667a&#8211;</p>
</blockquote>
<p>将formdata&nbsp; request&nbsp; raw 完整格式打印出来了</p>
<p><strong>接下来我们说说自定义24log 地址</strong></p>
<p><strong>自定义url地址，跟公共地址相比，可以设置 目标地址，如： 发送数据给24log 地址 =》日志镜像 =》 请求真是目标地址</strong></p>
<p>1、生成地址&nbsp; <a href="http://24log.chacuo.net/">http://24log.chacuo.net/</a></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2020/08/image1.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2020/08/image_thumb1.png" width="945" height="388"></a> </p>
<p>2、设置转发地址</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2020/08/image2.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2020/08/image_thumb2.png" width="931" height="421"></a> </p>
<p>访问 <a title="http://24log.chacuo.net/dump/5f4d0fb87e74f" href="http://24log.chacuo.net/dump/5f4d0fb87e74f">http://24log.chacuo.net/dump/5f4d0fb87e74f</a> =&gt; <a title="https://www.baidu.com" href="https://www.baidu.com">https://www.baidu.com</a> 了，我们试试看</p>
<p>3、访问试试看</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2020/08/image3.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2020/08/image_thumb3.png" width="932" height="329"></a> </p>
<p>已经读取到 baidu 代码，我们接下来看看 镜像到访问日志了</p>
<p>4、查看 访问日志</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2020/08/image4.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2020/08/image_thumb4.png" width="929" height="366"></a> </p>
<p>点击进去查看</p>
<p>5、查看详细内容</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2020/08/image5.png"><img title="image" style="border-left-width: 0px; border-right-width: 0px; border-bottom-width: 0px; display: inline; border-top-width: 0px" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2020/08/image_thumb5.png" width="416" height="527"></a> </p>
<p>可以查看到 完整请求头，返回内容，可以直接下载 源码以及，浏览</p>
<p>&nbsp;</p>
<p>该工具演示完了，怎么样还是一头雾水？ 不妨亲自去试试看 24log.chacuo.net&nbsp;&nbsp; 使用后，估计很快就知道怎么用了.&nbsp; 这里只是演示get请求，其实的&#8217;OPTIONS&#8217;, &#8216;GET&#8217;, &#8216;HEAD&#8217;, &#8216;POST&#8217;, &#8216;PUT&#8217;, &#8216;DELETE&#8217;, &#8216;TRACE&#8217; 都支持的，不妨试试！ 大家对工具有什么疑问，欢迎邮件建议！</p>
<p>&nbsp;
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p><strong></strong></p>
<blockquote><p style="text-indent: 0em">作者：<a href="http://blog.chacuo.net/" target="_blank">程默的博客</a>&nbsp; QQ:8292669 <br />原文网址：<a href="http://blog.chacuo.net/1436.html" target="_blank">http://blog.chacuo.net/1436.html</a> <br />订阅保持关注：<a href="http://blog.chacuo.net/feed" target="_blank">http://blog.chacuo.net/feed</a> <br />本文版权归作者所有，欢迎转载，请务必添加原文链接。</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/1436.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web应用安全 简介</title>
		<link>http://blog.chacuo.net/1353.html</link>
		<comments>http://blog.chacuo.net/1353.html#comments</comments>
		<pubDate>Mon, 09 Feb 2015 15:33:57 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[web应用安全]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=1353</guid>
		<description><![CDATA[一晃有一年多没有写博客了，每次想提笔写写，由于总是感觉要写的太多了，总是对自己说：“想清楚想明白再写”，这样就 [...]]]></description>
				<content:encoded><![CDATA[<p>一晃有一年多没有写博客了，每次想提笔写写，由于总是感觉要写的太多了，总是对自己说：“想清楚想明白再写”，这样就一直拖延。 另外一个原因是，觉得也没有什么人看，就这样耽搁下来了。 人是个有惰性的物种，只要惰性战胜了自己，就会找到很多理由让自己偷懒下。好了，闲话少说了，言归正传了。</p>
<p>&nbsp;</p>
<p>做了多年的web开发，遇到过很多刚刚毕业的兄弟以及刚入行的朋友。 经常在做一些功能时候，从技术设计本身出现各种问题。 他们在程序语言方面非常熟悉，但是做出来经常出现重大安全隐患！主要是用代码实现需求时候，考虑不全面，因此存在各种设计缺陷，产生技术漏洞！一些书本只会教我们 怎么样去实现功能， 而不会说 怎么样完美、无bug实现。这也是我 想写 应用安全的原因！ 希望给所有做web开发朋友，一些借鉴，写出更完美的程序！</p>
<p>上一段简单代码吧，限制只有某个a.com 来源站点，可以访问一个页面，我们代码一般如下：</p>
<div class="cnblogs_code" style="border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; border-bottom: #cccccc 1px solid; padding-bottom: 5px; padding-top: 5px; padding-left: 5px; border-left: #cccccc 1px solid; padding-right: 5px; background-color: #f5f5f5">
<pre>&lt;?<span style="color: #000000">php
</span><span style="color: #008000">//</span><span style="color: #008000">读取reffer</span>
<span style="color: #800080">$reffer</span> = <span style="color: #0000ff">isset</span>(<span style="color: #800080">$_SERVER</span>["HTTP_REFFER"])?<span style="color: #800080">$_SERVER</span>["HTTP_REFFER"]:''<span style="color: #000000">;

</span><span style="color: #0000ff">if</span>(<span style="color: #008080">strpos</span>(<span style="color: #800080">$reffer</span>,"a.com")===<span style="color: #0000ff">false</span><span style="color: #000000">)
{
    </span><span style="color: #0000ff">exit</span>('禁止访问!'<span style="color: #000000">);
}

</span><span style="color: #008000">//</span><span style="color: #008000">//继续执行</span></pre>
</div>
<p>以上代码，大家应该在一些demo里面，还有书本上面都有看到过，并且也会这样写的。 据说，weixin分享地址时候，也通过这种方式来检查是不是它们的域名呢。 </p>
<p>问题出在那里呢？</p>
<p>一个 url 地址格式是： 协议://user：<a href="mailto:pass@host/path?query#hash">pass@host/path?query#hash</a>&nbsp; ，可以看到 如果只是简单检测uri 里面是否有a.com ，是不是太容易被绕过了？ 只要自己地址是<a href="http://b.com#a.com">http://b.com#a.com</a>&nbsp; ，是不是一样可以访问我们资源了？</p>
<p>&nbsp;</p>
<p>哈哈， 是不是回想起自己某时候也这么写过呢！<img class="wlEmoticon wlEmoticon-smilewithtongueout" style="border-top-style: none; border-bottom-style: none; border-right-style: none; border-left-style: none" alt="吐舌笑脸" src="http://blog.chacuo.net/wp-content/uploads/2015/02/wlEmoticon-smilewithtongueout.png">&nbsp; ，希望这个例子能够激发您的兴趣，我们除了能实现逻辑，好的程序员，应该要做到安全稳定、实现高性能程序！ 当然，我们接下来主要讲的是怎么安全实现常见web应用功能。</p>
<p>接下来章节，我就以做一个 简单网页 ‘留言薄’来说吧！&nbsp; “啊？ 为什么是 做留言薄呢”， 其实一个留言板里面功能，也能涉及到我们方方面面了，麻雀虽小、五脏俱全啦！ 另外， 记忆最深刻的的，我第一次学习web程序时候，也是从留言薄开始的呢！</p>
<p>&nbsp;</p>
<p>待续……，先跟朋友们说晚安了！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/1353.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>网站备案突然取消了（8天不能访问）</title>
		<link>http://blog.chacuo.net/1195.html</link>
		<comments>http://blog.chacuo.net/1195.html#comments</comments>
		<pubDate>Fri, 11 Oct 2013 12:57:18 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[其它]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=1195</guid>
		<description><![CDATA[非常奇怪，网站没有做其它什么操作。突然10.3日开始就不能访问，由于国庆期间，一直在老家，操作站点不便。回深后 [...]]]></description>
				<content:encoded><![CDATA[<p>非常奇怪，网站没有做其它什么操作。突然10.3日开始就不能访问，由于国庆期间，一直在老家，操作站点不便。回深后，联系空间商，确定是备案被取消了， 网站不能访问了。 没有办法，独立主机上面的http协议被限制了请求。</p>
<p>现在临时将空间通过香港转发，感谢<a href="http://blog.liang360.com/" target="_blank">fubinhoo</a> 帮助。今天先做端口转发，然后再做反向代理。终于从香港vps 上面转发过来了。 目前新的备案还在申请中，转发可能会出现不稳定情况。望朋友们多多包涵，任何问题，欢迎Q我！</p>
<p>&nbsp;</p>
<p>谢谢大家！</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/1195.html/feed</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>XXencode 编码，XX编码介绍、XXencode编码转换原理、算法</title>
		<link>http://blog.chacuo.net/778.html</link>
		<comments>http://blog.chacuo.net/778.html#comments</comments>
		<pubDate>Fri, 02 Aug 2013 11:08:32 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[xxencode]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=778</guid>
		<description><![CDATA[Xxencode编码，也是一个二进制字符转换为普通打印字符方法。跟UUencode编码原理方法很相似，唯独不同 [...]]]></description>
				<content:encoded><![CDATA[<p>Xxencode编码，也是一个二进制字符转换为普通打印字符方法。跟<a title="UUencode编码原理" href="http://blog.chacuo.net/753.html" target="_blank">UUencode编码原理</a>方法很相似，唯独不同的是可打印字符不同。通个UUencode编码，我们知道它有个缺点就是，64个可打印字符中，有很多的特殊字符。而XXencode编码方法，对64个原字符有做规范。这里它有跟Base64类型了。都有指定可打印字符范围、及编号。Xxencode编码在上世纪后期，IBM大型机中得到很广泛的应用。现在逐渐被Base64编码转换方法所取代了。</p>
<p><strong>Xxencode编码原理</strong></p>
<p>XXencode将输入文本以每三个字节为单位进行编码。如果最后剩下的资料少于三个字节，不够的部份用零补齐。这三个字节共有24个Bit，以6bit为单位分为4个组，每个组以十进制来表示所出现的数值只会落在0到63之间。以所对应值的位置字符代替。它所选择的可打印字符是：+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz，一共64个字符。跟base64打印字符相比，就是uuencode多一个“-” 字符，少一个&#8221;/” 字符。 但是，它里面字符顺序与Base64完全不一样。与UUencode比较，这里面所选择字符，都是常见字符，没有特殊字符。这也决定它当年流行使用原因！</p>
<p>每60个编码输出（相当于45个输入字节）将输出为独立的一行，每行的开头会加上<b>长度字符</b>，除了最后一行之外，长度字符都应该是“h”这个字符（<b>45，刚好是64字符中，第45位&#8217;h’字符</b>），最后一行的长度字符为<b>剩下的字节数目</b> 在64字符中位置所代表字符。</p>
<p><strong>问题：</strong>uuencode编码转换为xxencode编码怎么样操作？</p>
<p>从2中编码原理来看，几乎一样。就是所用的64个字符不一样。一次，简单对uuencode转换后字符，逐位（处理’`’字符)减去32，然后得到一个值。这个值在xxencode 64字符中所对应位置字符替换即可。</p>
<p><strong>XXencode编码转换过程</strong></p>
<blockquote><pre>    <table class="table" border="1" rules="all" cellspacing="0" width="80%" align="center"><tbody><tr><td>原始字符 </td><td colspan="8">C </td><td colspan="8">a </td><td colspan="8">t </td></tr><tr><td>原始ASCII码（十进制） </td><td colspan="8">67 </td><td colspan="8">97 </td><td colspan="8">116 </td></tr><tr><td>ASCII码（二进制） </td><td>0 </td><td>1 </td><td>0 </td><td>0 </td><td>0 </td><td>0 </td><td>1 </td><td>1 </td><td>0 </td><td>1 </td><td>1 </td><td>0 </td><td>0 </td><td>0 </td><td>0 </td><td>1 </td><td>0 </td><td>1 </td><td>1 </td><td>1 </td><td>0 </td><td>1 </td><td>0 </td><td>0 </td></tr><tr><td>新的十进制数值 </td><td colspan="6">16 </td><td colspan="6">54 </td><td colspan="6">5 </td><td colspan="6">52 </td></tr><tr><td>编码后的XXencode字符 </td><td colspan="6">E</td><td colspan="6">q</td><td colspan="6">3 </td><td colspan="6">O</td></tr></tbody></table></pre>
<pre>字符串：'Cat‘ 编码后是：Eq3O</pre>
</blockquote>
<pre><strong>XXencode编码PHP实现过程</strong></pre>
<blockquote><pre class="brush: php; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: true; smart-tabs: true; tab-size: 4; toolbar: true;">/**
 *xxencode编码*
 *@author 程默
 *@copyright http://blog.chacuo.net/
 *@param string $src 待处理字符串
 *@return string encode编码完字符串
 */
function c_xx_encode($src)
{
	//64个可打印字符
	static $base="+-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    ///每次读取3个字节
    $lbyte = 3;
    ////将原始的3个字节转换为4个字节
    $slen=strlen($src);
    $smod = ($slen%$lbyte);
    $snum = floor($slen/$lbyte);
 
 
    $desc = array();
     
    //将剩下字节以0字节补齐
    $src = $smod===0?$src:$src.str_repeat("\0",$lbyte-$smod);
    $snum = $smod===0?$snum:$snum+1;
 
    for($i=0;$i&lt;$snum;$i++)
    {
        ////读取3个字节
        $_arr = array_map('ord',str_split(substr($src,$i*$lbyte,$lbyte)));
 
        ///计算每一个6位值
        $_dec = array();
        $_dec[]=$_arr[0]&gt;&gt;2;
        $_dec[]=(($_arr[0]&amp;3)&lt;&lt;4)|($_arr[1]&gt;&gt;4);
        $_dec[]=(($_arr[1]&amp;0xF)&lt;&lt;2)|($_arr[2]&gt;&gt;6);
        $_dec[]=$_arr[2]&amp;63;
         
        ///求每一位值，在64字符中所对应的字符
        foreach ($_dec as &amp;$v)
        {
           $v=$base[$v];
        }
        $desc = array_merge($desc,$_dec);
    }
     

    //每60个编码输出（相当于45个输入字节）将输出为独立的一行，每行的开头会加上长度字符，除了最后一行之外，长度字符都应该是'h'这个ASCII字符（45），最后一行的长度字符为剩下的字节数目,在64字符中对应字符。
    $abyte = 60;
    $crlf = "\r\n";
    $alen = count($desc);
    $anum = floor($alen/$abyte);
    $amod = ($alen%$abyte);
     
    $adesc = array();
     
    for ($i=0;$i&lt;$anum;$i++)
    {
        $adesc[]='h'.implode('',array_slice($desc,$i*$abyte,$abyte)).$crlf;
    }
     
    ///截取后面剩余数组长度
    if($amod!==0)
    {
        ///以下计算不满45字节编码情况
        $adesc[]=$base[$amod/4*$lbyte+($smod?$smod-$lbyte:$smod)].implode('',array_slice($desc,-$amod)).$crlf;
    }
     
    return implode('',$adesc);  
}</pre>
</blockquote>
<p>以上代码从uuencode编码做简单修改而来，基本上去掉+32一些地方。知道编码原理，其实我们很容易实现uuencode-&gt;xxencode转换的</p>
<blockquote>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/08/image2.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="xxencode编码" border="0" alt="xxencode编码" src="http://blog.chacuo.net/wp-content/uploads/2013/08/image_thumb2.png" width="821" height="311"></a> </p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/08/image3.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="xxencode编码" border="0" alt="xxencode编码" src="http://blog.chacuo.net/wp-content/uploads/2013/08/image_thumb3.png" width="821" height="405"></a> </p>
<p>以上转换后结果，与专业转换工具一致的。好了，通过学习这类用可打印字符表示二进制字节的编码方法。我们可以发现很多有趣东西！对应以后我们如果做自己的编码转换，可以给我们很多借鉴！欢迎朋友们给出自己的意见！</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/778.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>UUencode 编码，UU编码介绍、UUencode编码转换原理、算法</title>
		<link>http://blog.chacuo.net/753.html</link>
		<comments>http://blog.chacuo.net/753.html#comments</comments>
		<pubDate>Thu, 01 Aug 2013 10:16:47 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[uuencode]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=753</guid>
		<description><![CDATA[UUencode编码起先用在unix网络中，先是Unix系统下将二进制的资料借由uucp邮件系统传输的一个编码 [...]]]></description>
				<content:encoded><![CDATA[<p>UUencode编码起先用在unix网络中，先是Unix系统下将二进制的资料借由uucp邮件系统传输的一个编码程式，也是一种二进制到文字的编码。不属于MIME编码中一员。它也是定义了用可打印字符表示二进制文字一种方法，并不是一种新的编码集合。主要解决，二进制字符在传输、存储中问题。它早期在电子邮件中使用较多，最近这些年来基本上被MIME 中Base64所取代了。E-mail中一般采用UU、MIME、BINHEX三种编码标准! 我想，了解下这种编码将二进制字符转换为可打印字符实现思路！对我们以后做类似处理工作，应该会有很多的启示。</p>
<p><strong>UUencode编码过程</strong></p>
<p>Uuencode将输入资料以每三个字节为单位进行编码，如此重复进行。如果最后剩下的资料少于三个字节，不够的部份用零补齐。这三个字节共有24个Bit，以6-bit为单位分为4个群组，每个群组以十进制来表示所出现的数值只会落在0到63之间。将每个数加上32，所产生的结果刚好落在ASCII字符集中可打印字符（32-空白&#8230;95-底线）的范围之中。每60个编码输出（相当于45个输入字节）将输出为独立的一行，每行的开头会加上<b>长度字符</b>，除了最后一行之外，长度字符都应该是&#8217;M'这个ASCII字符（77=32+<b>45</b>），最后一行的长度字符为<b>32+剩下的字节数目</b>这个ASCII字符。如果是一个 0字节那它应该被转换为0&#215;60而不是0&#215;20，因为（前引用&#8217;`'）优于 0&#215;20（空格&#8217; &#8216;)。</p>
<p>特点一：看到特点了吧，也是64字符，也是一组6位。怎么,怎么,跟我们的<a title="base64算法、编码原理" href="http://blog.chacuo.net/719.html" target="_blank">base64</a>这么相似呢？是的，从这个定义中，我们确实发现它跟base64比起来很相似了。 </p>
<p>特点二：它定义64字符，不用写映射表，是通过加32转换到可打印字符范围中。比起base64，更为简单！</p>
<p><strong>思考问题：</strong>它的字符范围都是可打印字符，我们会发现64字符集合中，有很多是特殊字符:”!&#8221;#￥%&amp;‘（）*+=’” 等等。这些字符在不同应用中，可能都有些特殊用途。因此，在使用该编码时候，或许会出现一些问题。我想这也许是UUencode编码方法，逐渐被Base64所取代的原因吧。</p>
<blockquote><pre><font style="background-color: #ffffff" face="Arial"><strong>UUencode 64字符集</strong></font></pre>
<pre><table class="table" border="1" rules="all" cellspacing="0" width="80%" align="center"><tbody><tr valign="bottom"><th>可打印字符</th><th>十进制ASCII值</th><th>uuencode<br />二进制表示</th><th>uuencode<br />十进制表示</th><th>&nbsp;</th><th>可打印字符</th><th>十进制ASCII值</th><th>uuencode<br />二进制表示</th><th>uuencode<br />十进制表示</th></tr><tr><td align="middle">(space)</td><td align="middle">32</td><td align="middle">000 000</td><td align="middle">0</td><td>&nbsp;</td><td align="middle">@</td><td align="middle">64</td><td align="middle">100 000</td><td align="middle">32</td></tr><tr><td align="middle">!</td><td align="middle">33</td><td align="middle">000 001</td><td align="middle">1</td><td>&nbsp;</td><td align="middle">A</td><td align="middle">65</td><td align="middle">100 001</td><td align="middle">33</td></tr><tr><td align="middle">"</td><td align="middle">34</td><td align="middle">000 010</td><td align="middle">2</td><td>&nbsp;</td><td align="middle">B</td><td align="middle">66</td><td align="middle">100 010</td><td align="middle">34</td></tr><tr><td align="middle">#</td><td align="middle">35</td><td align="middle">000 011</td><td align="middle">3</td><td>&nbsp;</td><td align="middle">C</td><td align="middle">67</td><td align="middle">100 011</td><td align="middle">35</td></tr><tr><td align="middle">$</td><td align="middle">36</td><td align="middle">000 100</td><td align="middle">4</td><td>&nbsp;</td><td align="middle">D</td><td align="middle">68</td><td align="middle">100 100</td><td align="middle">36</td></tr><tr><td align="middle">%</td><td align="middle">37</td><td align="middle">000 101</td><td align="middle">5</td><td>&nbsp;</td><td align="middle">E</td><td align="middle">69</td><td align="middle">100 101</td><td align="middle">37</td></tr><tr><td align="middle">&amp;</td><td align="middle">38</td><td align="middle">000 110</td><td align="middle">6</td><td>&nbsp;</td><td align="middle">F</td><td align="middle">70</td><td align="middle">100 110</td><td align="middle">38</td></tr><tr><td align="middle">'</td><td align="middle">39</td><td align="middle">000 111</td><td align="middle">7</td><td>&nbsp;</td><td align="middle">G</td><td align="middle">71</td><td align="middle">100 111</td><td align="middle">39</td></tr><tr><td align="middle">(</td><td align="middle">40</td><td align="middle">001 000</td><td align="middle">8</td><td>&nbsp;</td><td align="middle">H</td><td align="middle">72</td><td align="middle">101 000</td><td align="middle">40</td></tr><tr><td align="middle">)</td><td align="middle">41</td><td align="middle">001 001</td><td align="middle">9</td><td>&nbsp;</td><td align="middle">I</td><td align="middle">73</td><td align="middle">101 001</td><td align="middle">41</td></tr><tr><td align="middle">*</td><td align="middle">42</td><td align="middle">001 010</td><td align="middle">10</td><td>&nbsp;</td><td align="middle">J</td><td align="middle">74</td><td align="middle">101 010</td><td align="middle">42</td></tr><tr><td align="middle">+</td><td align="middle">43</td><td align="middle">001 011</td><td align="middle">11</td><td>&nbsp;</td><td align="middle">K</td><td align="middle">75</td><td align="middle">101 011</td><td align="middle">43</td></tr><tr><td align="middle">,</td><td align="middle">44</td><td align="middle">001 100</td><td align="middle">12</td><td>&nbsp;</td><td align="middle">L</td><td align="middle">76</td><td align="middle">101 100</td><td align="middle">44</td></tr><tr><td align="middle">-</td><td align="middle">45</td><td align="middle">001 101</td><td align="middle">13</td><td>&nbsp;</td><td align="middle">M</td><td align="middle">77</td><td align="middle">101 101</td><td align="middle">45</td></tr><tr><td align="middle">.</td><td align="middle">46</td><td align="middle">001 110</td><td align="middle">14</td><td>&nbsp;</td><td align="middle">N</td><td align="middle">78</td><td align="middle">101 110</td><td align="middle">46</td></tr><tr><td align="middle">/</td><td align="middle">47</td><td align="middle">001 111</td><td align="middle">15</td><td>&nbsp;</td><td align="middle">O</td><td align="middle">79</td><td align="middle">101 111</td><td align="middle">47</td></tr><tr><td align="middle">0</td><td align="middle">48</td><td align="middle">010 000</td><td align="middle">16</td><td>&nbsp;</td><td align="middle">P</td><td align="middle">80</td><td align="middle">110 000</td><td align="middle">48</td></tr><tr><td align="middle">1</td><td align="middle">49</td><td align="middle">010 001</td><td align="middle">17</td><td>&nbsp;</td><td align="middle">Q</td><td align="middle">81</td><td align="middle">110 001</td><td align="middle">49</td></tr><tr><td align="middle">2</td><td align="middle">50</td><td align="middle">010 010</td><td align="middle">18</td><td>&nbsp;</td><td align="middle">R</td><td align="middle">82</td><td align="middle">110 010</td><td align="middle">50</td></tr><tr><td align="middle">3</td><td align="middle">51</td><td align="middle">010 011</td><td align="middle">19</td><td>&nbsp;</td><td align="middle">S</td><td align="middle">83</td><td align="middle">110 011</td><td align="middle">51</td></tr><tr><td align="middle">4</td><td align="middle">52</td><td align="middle">010 100</td><td align="middle">20</td><td>&nbsp;</td><td align="middle">T</td><td align="middle">84</td><td align="middle">110 100</td><td align="middle">52</td></tr><tr><td align="middle">5</td><td align="middle">53</td><td align="middle">010 101</td><td align="middle">21</td><td>&nbsp;</td><td align="middle">U</td><td align="middle">85</td><td align="middle">110 101</td><td align="middle">53</td></tr><tr><td align="middle">6</td><td align="middle">54</td><td align="middle">010 110</td><td align="middle">22</td><td>&nbsp;</td><td align="middle">V</td><td align="middle">86</td><td align="middle">110 110</td><td align="middle">54</td></tr><tr><td align="middle">7</td><td align="middle">55</td><td align="middle">010 111</td><td align="middle">23</td><td>&nbsp;</td><td align="middle">W</td><td align="middle">87</td><td align="middle">110 111</td><td align="middle">55</td></tr><tr><td align="middle">8</td><td align="middle">56</td><td align="middle">011 000</td><td align="middle">24</td><td>&nbsp;</td><td align="middle">X</td><td align="middle">88</td><td align="middle">111 000</td><td align="middle">56</td></tr><tr><td align="middle">9</td><td align="middle">57</td><td align="middle">011 001</td><td align="middle">25</td><td>&nbsp;</td><td align="middle">Y</td><td align="middle">89</td><td align="middle">111 001</td><td align="middle">57</td></tr><tr><td align="middle">:</td><td align="middle">58</td><td align="middle">011 010</td><td align="middle">26</td><td>&nbsp;</td><td align="middle">Z</td><td align="middle">90</td><td align="middle">111 010</td><td align="middle">58</td></tr><tr><td align="middle">;</td><td align="middle">59</td><td align="middle">011 011</td><td align="middle">27</td><td>&nbsp;</td><td align="middle">[</td><td align="middle">91</td><td align="middle">111 011</td><td align="middle">59</td></tr><tr><td align="middle">&lt;</td><td align="middle">60</td><td align="middle">011 100</td><td align="middle">28</td><td>&nbsp;</td><td align="middle">\</td><td align="middle">92</td><td align="middle">111 100</td><td align="middle">60</td></tr><tr><td align="middle">=</td><td align="middle">61</td><td align="middle">011 101</td><td align="middle">29</td><td>&nbsp;</td><td align="middle">]</td><td align="middle">93</td><td align="middle">111 101</td><td align="middle">61</td></tr><tr><td align="middle">&gt;</td><td align="middle">62</td><td align="middle">011 110</td><td align="middle">30</td><td>&nbsp;</td><td align="middle">^</td><td align="middle">94</td><td align="middle">111 110</td><td align="middle">62</td></tr><tr><td align="middle">?</td><td align="middle">63</td><td align="middle">011 111</td><td align="middle">31</td><td>&nbsp;</td><td align="middle">_</td><td align="middle">95</td><td align="middle">111 111</td><td align="middle">63</td></tr><tr><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td>&nbsp;</td><td align="middle">`</td><td align="middle">96</td><td align="middle">(1) 000 000</td><td align="middle">64</td></tr></tbody></table>
</pre>
</blockquote>
<p><strong>UUencode编码转换过程</strong></p>
<blockquote><pre><table class="table" border="1" rules="all" cellspacing="0" width="80%" align="center"><tbody><tr><td>原始字符</td><td colspan="8">C</td><td colspan="8">a</td><td colspan="8">t</td></tr><tr><td>原始ASCII码（十进制）</td><td colspan="8">67</td><td colspan="8">97</td><td colspan="8">116</td></tr><tr><td>ASCII码（二进制）</td><td>0</td><td>1</td><td>0</td><td>0</td><td>0</td><td>0</td><td>1</td><td>1</td><td>0</td><td>1</td><td>1</td><td>0</td><td>0</td><td>0</td><td>0</td><td>1</td><td>0</td><td>1</td><td>1</td><td>1</td><td>0</td><td>1</td><td>0</td><td>0</td></tr><tr><td>新的十进制数值</td><td colspan="6">16</td><td colspan="6">54</td><td colspan="6">5</td><td colspan="6">52</td></tr><tr><td>+32</td><td colspan="6">48</td><td colspan="6">86</td><td colspan="6">37</td><td colspan="6">84</td></tr><tr><td>编码后的Uuencode字符</td><td colspan="6">0</td><td colspan="6">V</td><td colspan="6">%</td><td colspan="6">T</td></tr></tbody></table></pre>
<pre>字符串：'Cat‘ 编码后是：oV%T</pre>
</blockquote>
<p><strong>UUencode PHP实现过程</strong></p>
<p>编码转换过程，与Base64类似！下面代码是实现过程，我们可以看看转换方法！</p>
<blockquote><pre class="brush: php; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: true; smart-tabs: true; tab-size: 4; toolbar: true;">/**
 *uuencode编码*
 *@author 程默
 *@copyright http://blog.chacuo.net/
 *@param string $src 待处理字符串
 *@return string encode编码完字符串
 */
function c_uu_encode($src)
{
	///每次读取3个字节
	$lbyte = 3;
	////将原始的3个字节转换为4个字节
	$slen=strlen($src);
	$smod = ($slen%$lbyte);
	$snum = floor($slen/$lbyte);


	$desc = array();
	
	//将剩下字节以0字节补齐
	$src = $smod===0?$src:$src.str_repeat("\0",$lbyte-$smod);
	$snum = $smod===0?$snum:$snum+1;

	for($i=0;$i&lt;$snum;$i++)
	{
		////读取3个字节
		$_arr = array_map('ord',str_split(substr($src,$i*$lbyte,$lbyte)));

		///计算每一个6位值
		$_dec = array();
		$_dec[]=$_arr[0]&gt;&gt;2;
		$_dec[]=(($_arr[0]&amp;3)&lt;&lt;4)|($_arr[1]&gt;&gt;4);
		$_dec[]=(($_arr[1]&amp;0xF)&lt;&lt;2)|($_arr[2]&gt;&gt;6);
		$_dec[]=$_arr[2]&amp;63;
		
		///对每个6位值加上32，读取ascii码 如果6位值是0，以字符"`"代替
		foreach ($_dec as &amp;$v)
		{
			$v = $v===0?'`':chr($v+32);
		}
		$desc = array_merge($desc,$_dec);
	}
	//return implode('',$desc);
	
	///以上代码只是进行转换，没有进一步进行
	//每60个编码输出（相当于45个输入字节）将输出为独立的一行，每行的开头会加上长度字符，除了最后一行之外，长度字符都应该是'M'这个ASCII字符（77=32+45），最后一行的长度字符为32+剩下的字节数目这个ASCII字符。
	$abyte = 60;
	$crlf = "\r\n";
	$alen = count($desc);
	$anum = floor($alen/$abyte);
	$amod = ($alen%$abyte);
	
	$adesc = array();
	
	for ($i=0;$i&lt;$anum;$i++)
	{
		$adesc[]='M'.implode('',array_slice($desc,$i*$abyte,$abyte)).$crlf;
	}
	
	///截取后面剩余数组长度
	if($amod!==0)
	{
		///以下计算不满45字节编码情况
		$adesc[]=chr($amod/4*3+32+($smod?$smod-$lbyte:$smod)).implode('',array_slice($desc,-$amod)).$crlf;
	}
	
	return implode('',$adesc);	
}</pre>
<p>&nbsp;</p>
</blockquote>
<p>以上只是按照转换过程，通过PHP代码实现方法！目前PHP没有UUencode转换模块！</p>
<blockquote>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/08/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UUencode编码" border="0" alt="UUencode编码" src="http://blog.chacuo.net/wp-content/uploads/2013/08/image_thumb.png" width="712" height="208"></a> </p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/08/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="UUencode编码" border="0" alt="UUencode编码" src="http://blog.chacuo.net/wp-content/uploads/2013/08/image_thumb1.png" width="714" height="409"></a> </p>
<p>该代码转换结果，跟使用工具转换结果一致。我查看了线上一些转换方法，很多结果不一致！最好，大家使用在线工具转换前，做一下比较！没有做过验证的代码，可能会给你带来麻烦！欢迎分享你的方法！</p>
</blockquote>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/753.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Base64 编码介绍、Base64编码转换原理、算法</title>
		<link>http://blog.chacuo.net/719.html</link>
		<comments>http://blog.chacuo.net/719.html#comments</comments>
		<pubDate>Tue, 30 Jul 2013 12:29:19 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[base64]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=719</guid>
		<description><![CDATA[Base64编码，是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方 [...]]]></description>
				<content:encoded><![CDATA[<p>Base64编码，是我们程序开发中经常使用到的编码方法。它是一种基于用64个可打印字符来表示二进制数据的表示方法。它通常用作存储、传输一些二进制数据编码方法！也是MIME（多用途互联网邮件扩展，主要用作电子邮件标准）中一种可打印字符表示二进制数据的常见编码方法！它其实只是定义用可打印字符传输内容一种方法，并不会产生新的字符集！有时候，我们学习转换的思路后，我们其实也可以结合自己的实际需要，构造一些自己接口定义编码方式。好了，我们一起看看，它的转换思路吧！</p>
<p><strong>Base64实现转换原理</strong></p>
<p>它是用64个可打印字符表示二进制所有数据方法。由于2的6次方等于64，所以可以用每6个位元为一个单元，对应某个可打印字符。我们知道三个字节有24个位元，就可以刚好对应于4个Base64单元，即3个字节需要用4个Base64的可打印字符来表示。在Base64中的可打印字符包括字母A-Z、a-z、数字0-9 ，这样共有62个字符，此外两个可打印符号在不同的系统中一般有所不同。但是，我们经常所说的Base64另外2个字符是：“+/”。这64个字符，所对应表如下。</p>
<blockquote><table class="table" border="1" rules="all" cellspacing="0" width="80%" align="center">
<tbody>
<tr>
<th scope="col">编号</th>
<th scope="col">字符</th>
<th rowspan="18">&nbsp;</th>
<th scope="col">编号</th>
<th scope="col">字符</th>
<th rowspan="18">&nbsp;</th>
<th scope="col">编号</th>
<th scope="col">字符</th>
<th rowspan="18">&nbsp;</th>
<th scope="col">编号</th>
<th scope="col">字符</th>
</tr>
<tr>
<td>0</td>
<td>A</td>
<td>16</td>
<td>Q</td>
<td>32</td>
<td>g</td>
<td>48</td>
<td>w</td>
</tr>
<tr>
<td>1</td>
<td>B</td>
<td>17</td>
<td>R</td>
<td>33</td>
<td>h</td>
<td>49</td>
<td>x</td>
</tr>
<tr>
<td>2</td>
<td>C</td>
<td>18</td>
<td>S</td>
<td>34</td>
<td>i</td>
<td>50</td>
<td>y</td>
</tr>
<tr>
<td>3</td>
<td>D</td>
<td>19</td>
<td>T</td>
<td>35</td>
<td>j</td>
<td>51</td>
<td>z</td>
</tr>
<tr>
<td>4</td>
<td>E</td>
<td>20</td>
<td>U</td>
<td>36</td>
<td>k</td>
<td>52</td>
<td>0</td>
</tr>
<tr>
<td>5</td>
<td>F</td>
<td>21</td>
<td>V</td>
<td>37</td>
<td>l</td>
<td>53</td>
<td>1</td>
</tr>
<tr>
<td>6</td>
<td>G</td>
<td>22</td>
<td>W</td>
<td>38</td>
<td>m</td>
<td>54</td>
<td>2</td>
</tr>
<tr>
<td>7</td>
<td>H</td>
<td>23</td>
<td>X</td>
<td>39</td>
<td>n</td>
<td>55</td>
<td>3</td>
</tr>
<tr>
<td>8</td>
<td>I</td>
<td>24</td>
<td>Y</td>
<td>40</td>
<td>o</td>
<td>56</td>
<td>4</td>
</tr>
<tr>
<td>9</td>
<td>J</td>
<td>25</td>
<td>Z</td>
<td>41</td>
<td>p</td>
<td>57</td>
<td>5</td>
</tr>
<tr>
<td>10</td>
<td>K</td>
<td>26</td>
<td>a</td>
<td>42</td>
<td>q</td>
<td>58</td>
<td>6</td>
</tr>
<tr>
<td>11</td>
<td>L</td>
<td>27</td>
<td>b</td>
<td>43</td>
<td>r</td>
<td>59</td>
<td>7</td>
</tr>
<tr>
<td>12</td>
<td>M</td>
<td>28</td>
<td>c</td>
<td>44</td>
<td>s</td>
<td>60</td>
<td>8</td>
</tr>
<tr>
<td>13</td>
<td>N</td>
<td>29</td>
<td>d</td>
<td>45</td>
<td>t</td>
<td>61</td>
<td>9</td>
</tr>
<tr>
<td>14</td>
<td>O</td>
<td>30</td>
<td>e</td>
<td>46</td>
<td>u</td>
<td>62</td>
<td>+</td>
</tr>
<tr>
<td>15</td>
<td>P</td>
<td>31</td>
<td>f</td>
<td>47</td>
<td>v</td>
<td>63</td>
<td>/</td>
</tr>
</tbody>
</table>
</blockquote>
<p><strong>Base64编码转换算法、转换原理</strong></p>
<blockquote><p>转换的时候，将三个byte的数据，先后放入一个24bit的缓冲区中，先来的byte占高位。数据不足3byte的话，于缓冲区中剩下的bit用0补足。然后，每次取出6个bit，按照其值选择<code><br />ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/</code>中的字符作为编码后的输出。不断进行，直到全部输入数据转换完成。
<p>如果最后剩下两个输入数据，在编码结果后加1个“=”；如果最后剩下一个输入数据，编码结果后加2个“=”；如果没有剩下任何数据，就什么都不要加，这样才可以保证资料还原的正确性。
<p>编码后的数据比原始数据略长，为原来的4/3。无论什么样的字符都会全部被编码，因此不像<a href="http://blog.chacuo.net/494.html">Quoted-printable</a> 编码，还保留部分可打印字符。所以，它的可读性不如<a href="http://blog.chacuo.net/494.html">Quoted-printable</a> 编码！</p>
<p>
<table class="table" border="1" rules="all" cellspacing="0" width="80%" align="center">
<tbody>
<tr>
<th scope="row">文本</th>
<td colspan="8" align="middle"><b>M</b></td>
<td colspan="8" align="middle"><b>a</b></td>
<td colspan="8" align="middle"><b>n</b></td>
</tr>
<tr>
<th scope="row">ASCII编码</th>
<td colspan="8" align="middle">77</td>
<td colspan="8" align="middle">97</td>
<td colspan="8" align="middle">110</td>
</tr>
<tr>
<th scope="row">二进制位</th>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<th scope="row">索引</th>
<td colspan="6" align="middle">19</td>
<td colspan="6" align="middle">22</td>
<td colspan="6" align="middle">5</td>
<td colspan="6" align="middle">46</td>
</tr>
<tr>
<th scope="row">Base64编码</th>
<td colspan="6" align="middle"><b>T</b></td>
<td colspan="6" align="middle"><b>W</b></td>
<td colspan="6" align="middle"><b>F</b></td>
<td colspan="6" align="middle"><b>u</b></td>
</tr>
</tbody>
</table>
<p>M的Ascii码是77,前六位对应值为19，对应base64字符是T，如此类推。其它字符编码就可以自动转换得到！我们看看另外不是刚好是3个字节的情况！</p>
<p>&nbsp;</p>
<p>
<table class="table" border="1" rules="all" cellspacing="0" width="80%" align="center">
<tbody>
<tr>
<th scope="row">文本（1 Byte）</th>
<td colspan="8" align="middle"><b>A</b></td>
<td colspan="8" align="middle">&nbsp;</td>
<td colspan="8" align="middle">&nbsp;</td>
</tr>
<tr>
<th scope="row">二进制位</th>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<th scope="row">二进制位（补0）</th>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td><b>0</b></td>
<td><b>0</b></td>
<td><b>0</b></td>
<td><b>0</b></td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
</tr>
<tr>
<th scope="row">Base64编码</th>
<td colspan="6" align="middle"><b>Q</b></td>
<td colspan="6" align="middle"><b>Q</b></td>
<td colspan="6" align="middle"><strong>=</strong></td>
<td colspan="6" align="middle"><strong>=</strong></td>
</tr>
<tr>
<th scope="row">文本（2 Byte）</th>
<td colspan="8" align="middle"><b>B</b></td>
<td colspan="8" align="middle"><b>C</b></td>
<td colspan="8" align="middle">&nbsp;</td>
</tr>
<tr>
<th scope="row">二进制位</th>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>&nbsp;</td>
<td>&nbsp;</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr>
<th scope="row">二进制位（补0）</th>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td><b>0</b></td>
<td><b>0</b></td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
<td>x</td>
</tr>
<tr>
<th scope="row">Base64编码</th>
<td colspan="6" align="middle"><b>Q</b></td>
<td colspan="6" align="middle"><b>k</b></td>
<td colspan="6" align="middle"><b>M</b></td>
<td colspan="6" align="middle">&nbsp;<strong>=</strong></td>
</tr>
</tbody>
</table>
</blockquote>
<p><strong>Base64转换代码实现</strong></p>
<p>既然知道了方法，那么我们如果要自己写个简单转换，好像也是很容易的！下面，我写下我做转换php代码！</p>
<blockquote><p>&nbsp;
<pre class="brush: php; auto-links: true; collapse: false; first-line: 1; gutter: true; html-script: false; light: false; ruler: true; smart-tabs: true; tab-size: 4; toolbar: true;">/**
 *base64编码方法、本方法只是做base64转换过程代码举例说明，通过该例子可以任意改造不同语言版
 *@author 程默
 *@copyright http://blog.chacuo.net
 *@param $src 原字符串
 *@return string base64字符串*
 */
function c_base64_encode($src)
{
	static $base="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
	
	////将原始的3个字节转换为4个字节
	$slen=strlen($src);
	$smod = ($slen%3);
	$snum = floor($slen/3);
	
	
	$desc = array();
	
	for($i=0;$i&lt;$snum;$i++)
	{
		////读取3个字节
		$_arr = array_map('ord',str_split(substr($src,$i*3,3)));
		
		///计算每一个base64值
		$_dec0= $_arr[0]&gt;&gt;2;
		$_dec1= (($_arr[0]&amp;3)&lt;&lt;4)|($_arr[1]&gt;&gt;4);
		$_dec2= (($_arr[1]&amp;0xF)&lt;&lt;2)|($_arr[2]&gt;&gt;6);	
		$_dec3= $_arr[2]&amp;63;

		$desc = array_merge($desc,array($base[$_dec0],$base[$_dec1],$base[$_dec2],$base[$_dec3]));
	}
	
	if($smod==0) return implode('',$desc);
	
	///计算非3倍数字节
	$_arr = array_map('ord',str_split(substr($src,$snum*3,3)));
	$_dec0= $_arr[0]&gt;&gt;2;
	///只有一个字节
	if(!isset($_arr[1]))
	{
		$_dec1= (($_arr[0]&amp;3)&lt;&lt;4);
		$_dec2=$_dec3="=";
	}
	else 
	{
		///2个字节
		$_dec1= (($_arr[0]&amp;3)&lt;&lt;4)|($_arr[1]&gt;&gt;4);
		$_dec2= $base[($_arr[1]&amp;7)&lt;&lt;2];
		$_dec3="=";
	}
	$desc = array_merge($desc,array($base[$_dec0],$base[$_dec1],$_dec2,$_dec3));
	return implode('',$desc);
}</pre>
</blockquote>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image9.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="base64编码转换原理" border="0" alt="base64编码转换原理" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb9.png" width="825" height="459"></a> </pre>
</blockquote>
<p>好了，通过这个例子，我想base64编码转换原理、算法有些了解了吧！它转换过程很简单，只需要做个映射表，然后将原先做一些移位运算就可以完成！我们通过该例子，是不是可以做个自己的base32这类的编码呢！欢迎朋友们交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/719.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quoted-printable 编码介绍、编码解码转换</title>
		<link>http://blog.chacuo.net/494.html</link>
		<comments>http://blog.chacuo.net/494.html#comments</comments>
		<pubDate>Wed, 24 Jul 2013 11:59:18 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[quoted-printable]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=494</guid>
		<description><![CDATA[Quoted-printable 可译为“可打印字符引用编码”、“使用可打印字符的编码”，我们收邮件，查看信件 [...]]]></description>
				<content:encoded><![CDATA[<p>Quoted-printable 可译为“可打印字符引用编码”、“使用可打印字符的编码”，我们收邮件，查看信件原始信息，经常会看到这种类型的编码！</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image8.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Quoted-printable编码" border="0" alt="Quoted-printable编码" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb8.png" width="547" height="296"></a></pre>
<pre>最多时候，我们在邮件头里面能够看到这样的编码！Content-Transfer-Encoding:quoted-printable</pre>
<pre>&nbsp;</pre>
</blockquote>
<p>它是<b>多用途互联网邮件扩展</b>（MIME) 一种实现方式。其中MIME是一个互联网标准，它扩展了电子邮件标准，致力于使其能够支持非ASCII字符、二进制格式附件等多种格式的邮件消息。目前http协议中，很多采用MIME框架！quoted-printable 就是说用一些可打印常用字符，表示一个字节（8位）中所有非打印字符方法！</p>
<p><strong>Quoted-printable编码方法</strong></p>
<blockquote>
<p>任何一个8位的字节值可编码为3个字符：一个等号&#8221;=&#8221;后跟随两个十六进制数字(0–9或A–F)表示该字节的数值.例如，ASCII码换页符（十进制值为12）可以表示为&#8221;=0C&#8221;, 等号&#8221;=&#8221;（十进制值为61）必须表示为&#8221;=3D&#8221;. 除了可打印ASCII字符与换行符以外，所有字符必须表示为这种格式.</p>
<p>所有可打印ASCII字符(十进制值的范围为33到126)可用ASCII字符编码来直接表示, 但是等号&#8221;=&#8221;(十进制值为61)不可以这样直接表示.ASCII的水平制表符(tab)与空格符, 十进制为9和32, 如果不出现在行尾则可以用其ASCII字符编码直接表示。如果这两个字符出现在行尾，必须QP编码表示为&#8221;=09&#8243; (tab)或&#8221;=20&#8243; (space).</p>
<p>如果数据中包含有意义的行结束标志，必须转换为ASCII回车(CR)换行(LF)序列，既不能用原来的ASCII字符也不能用QP编码的&#8221;=&#8221;转义字符序列。 相反，如果字节值13与10有其它的不是行结束的含义，它们必须QP编码为=0D与=0A.</p>
<p>quoted-printable编码的数据的每行长度不能超过76个字符. 为满足此要求又不改变被编码文本，在QP编码结果的每行末尾加上软换行(soft line break). 即在每行末尾加上一个&#8221;=&#8221;, 但并不会出现在解码得到的文本中. </p>
<p>例如：If you believe that truth=beauty, then surely mathematics is the most beautiful branch of philosophy. 编码后结果是</p>
<pre>If you believe that truth=3Dbeauty, then surely=20=
mathematics is the most beautiful branch of philosophy.</pre>
</blockquote>
<p>编码里面，有几个特定限定，一些可打印字符不用编码，当然如果你按照规范编码后，也一样可以显示的！因此自己简单自己实现该编码:</p>
<blockquote><pre>function quoted_printable_encode($string) { <br />&nbsp;&nbsp;&nbsp; return preg_replace('/[^\r\n]{73}[^=\r\n]{2}/', "$0=\r\n", str_replace("%","=",<br />rawurlencode($string))); <br />} </pre>
<p>一个函数就可以，将所有字符串urlencode转换后，%号替换为”=”号，然后对非\r\n超过73连续字符，后面加一个=\r\n。这个是简单实现方法！ 按照该编码详细说明里面，有些空格、换行，还有一些特殊字符可以不用转换。不过一起转换了，也不会有影响！</p>
</blockquote>
<p>很多时候，我们用些常见字符表示所有8位其它非打印字符，这种通过，Quoted-printable编码，只是对该字节转为16进制后，做简单增加前缀！然后做些特殊字符处理即可！ 它的简单，及编码高效，也让该编码在邮件格式里面，得到了广泛使用！好了，就到这里，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/494.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ISO-8859-1 、Latin-1 西欧编码介绍及应用</title>
		<link>http://blog.chacuo.net/371.html</link>
		<comments>http://blog.chacuo.net/371.html#comments</comments>
		<pubDate>Fri, 19 Jul 2013 11:47:21 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[iso-8859-1]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=371</guid>
		<description><![CDATA[这些编码，早些时候在一些应用软件中经常看到，估计很多朋友也看到了，这些编码了！ 从这个图，我们可以看到这类编码 [...]]]></description>
				<content:encoded><![CDATA[<p>这些编码，早些时候在一些应用软件中经常看到，估计很多朋友也看到了，这些编码了！</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image4.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="iso-8859-1字符集应用" border="0" alt="iso-8859-1字符集应用" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb4.png" width="900" height="392"></a> </pre>
<p>从这个图，我们可以看到这类编码应用很广泛，那么我们一起看看，iso-8859-1字符集，到底是什么样字符集，有那些字符！为什么，它应用可以这么广泛！</p>
</blockquote>
<p>计算机上面流行第一个字符集，是ascii码，是0-127 一个128字符。每个字符在里面有个对应编号，分别是0-127。如果用二进制表示，刚好是7位。这个字符集，在前期表示英文字符已经足够。后来，随着计算机普及，越来越多国家（欧洲），开始应用计算机，他们发现7位，共128字符。已经不能描述他们常用的字符了。因此想到要兼容ascii字符集，就指定了扩展ASCII字符集。最多是0-255,256个字符。其中0-127 128字符及位置编码 完全兼容ascii码。只是扩展了128-255位置编入了新字符！</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image7.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="iso-8859-1字符集" border="0" alt="iso-8859-1字符集" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb7.png" width="864" height="677"></a> </pre>
<p>该字符集，完全兼容ascii字符集，并且是刚好可以用一个字节表示里面所有字符位置。又称为扩展Ascii码！这也是第一个iso-8859-1字符集。又叫：Latin-1 编码(西欧编码)，后来陆续出了iso-8859-2…-15字符集。都是完全兼容ascii码的。</p>
<p>&nbsp;</p>
</blockquote>
<blockquote>
<p>说下几个概念吧，什么是字符集，什么是字符编码?</p>
<p>1、字符集，表示由一些指定的字符的所组成集合！ascii字符集，里面有128个字符</p>
<p>2、字符编码，每个字符集中字符，都有一个固定的编号，也叫该字符在字符集中的的编码！如：ascii字符集中，a 字符编码是97。</p>
<p>相同字符，会出现在多个字符集中吗，相同字符在不同字符集中编码一样吗？</p>
<p>从上面例子，我们可以看到，ascii字符集、iso-8859-1字符集 有128个字符相同的。经常相同的字符，可以出现在各个字符集中。但是，每个字符集对字符编号方式可能不同，因此，相同字符，在不同字符集中，编码结果可能不一样。当然，也有一样的！象ascii中所有字符编码，在iso-8859-1字符集中，都一样的。</p>
<p>&nbsp;</p>
</blockquote>
<p>弄清楚关于、字符集，字符编码概念。我们还有几个必须掌握的。就是，计算机是怎么样储存，显示字符的呢？</p>
<p>一个文件有很多符号组成，各式各样的！实际，计算机在存储时候，只是写入该字符所对应的字符编码值。将它存于磁盘或者在网络中传输！如果要显示时候，通过对应字符集中，字符编码值。然后可以转换到计算机 通用的字符集的对应字符编码。计算机每个字符形状，图像长相，都在字体中。然后，通过转换得到通用字符集的字符编码，找到对应的字符，及字体形状，然后显示出来！</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image6.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="字符存储方式" border="0" alt="字符存储方式" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb6.png" width="886" height="468"></a> </pre>
<pre><font color="#0000ff">字符在计算机存储、传输都是该字符所在字符集中编码值 </font></pre>
<pre>&nbsp;</pre>
</blockquote>
<p>好了，中间我们对字符概念做了很多的阐述、说明！下面，我们继续本页主题iso-8859-1字符集了。 它为什么能够这么广泛应用呢？</p>
<p>我们知道，单字节最多可以表示256字符，实际上很多字符（目前unicode有几十万字符），都需要用多个字节来存储！计算机在存储传输都以字节为单位！因此单字节的： iso-8859-1 是存储的最小单元。所以，无论你是多少个字节组成的字符，以单字节一个一个存储、传输！都不会改变原来的值，都可以很好保存它的值！<font color="#0000ff">计算机乱码，出现在显示的时候，在不正确的字符集中，查找对应字符编码的字符！经常是，编码选择字符集，跟做显示选择字符集不一致造成的！</font></p>
<p><p>在复制文件、传输文件不会造成字符编码问题。而出现问题时候，是字符做显示，或者将显示字符存储的时候，会出现问题！好了，这里面说的是iso-8859-1 其实，更多的是说说，字符编码的一些常识！明白这些，对于iso-8859-1的一些特点理解，可能 更容易了！</p>
<p>可能以前有朋友就问，我mysql是存中文的，为什么我选择字符集是Latin-1 ，是不是就出现乱码了。其实不会，它只是将接到任何字节，按照单字节，逐个逐个存储的。然后，读取时候，也逐个逐个字节的读出。没有改变任何保存内容，也没有做任何编码转换！这是，最为安全的！好了，就到这里了，欢迎朋友们交流！</p></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/371.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web应用安全参数检测方法（检测输入参数方法）</title>
		<link>http://blog.chacuo.net/360.html</link>
		<comments>http://blog.chacuo.net/360.html#comments</comments>
		<pubDate>Fri, 19 Jul 2013 08:48:33 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[参数检查]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=360</guid>
		<description><![CDATA[前面我们说到，web应用安全的基数是，做好参数检测！就像是小区防止小偷，必须把好所有进入门。然后，对进入人员进 [...]]]></description>
				<content:encoded><![CDATA[<p>前面我们说到，web应用安全的基数是，做好参数检测！就像是小区防止小偷，必须把好所有进入门。然后，对进入人员进行检测！这些我们都清楚的，就是有时候在web应用中，对输入参数检测时候发现困难！因为，输入参数字符可以各种各样，长度也不相同！我们从什么维度准确标识出我所需要的格式呢？</p>
<p>这里我观点是，应用对参数检测可以分为2个关卡，第一个关卡可以是，保证参数输入安全。第二个关卡是保证它是业务所需要的值。一个应用，保证安全是最基础的。我们第一关检测参数，怎么样做比较好呢？</p>
<p><strong>标识参数方法？</strong></p>
<p>所有web传入都是字符串，我们怎么样标识字符串呢？字符串都是有字符组成的，常见是ascii码，对于中文网站，有gb2312,gbk等字符。从这里看，字符个数会很多。它们之间如果做长度不一组合字符串，将会更多了。 因此，再一次说明，不要用现在字符串方法，来检测！有可能你需要限制是无底洞！可以说，对于我们一个web应用参数，90%以上，基本在ascii码就可以，很少参数会突变到这100多个字符范围。所以，标识一个字符串，可以从以下2个方面来限制：</p>
<blockquote><p>1、字符串 中字符范围 （如：如果是手机号0-9，用户名可能是字母+数字之类）</p>
<p>2、字符串 长度 （如手机号是：11位，用户名可能是：6-15位）</p>
</blockquote>
<p>以上方法可以保证，不在用户需要字符范围的字符，一定不能进入后端！我们看看一般例子！</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #009933; font-style: italic;">/**
*读取get值
*@copyright  http://blog.chacuo.net
*@author 8292669
*@param $k string get参数名称
*@param $p string 正则表达式内容
*@return string|array 读取值
*/</span>
<span style="color: #000000; font-weight: bold;">function</span> input_get<span style="color: #009900;">&#40;</span><span style="color: #000088;">$k</span><span style="color: #339933;">,</span><span style="color: #000088;">$p</span><span style="color: #339933;">=</span><span style="color: #0000ff;">'.*'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$v</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$k</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$k</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">is_array</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #000088;">$_v</span> <span style="color: #339933;">=</span> <span style="color: #990000;">array</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
		<span style="color: #b1b100;">foreach</span> <span style="color: #009900;">&#40;</span><span style="color: #000088;">$v</span> <span style="color: #b1b100;">as</span> <span style="color: #000088;">$k</span><span style="color: #339933;">=&gt;</span><span style="color: #000088;">$_v1</span><span style="color: #009900;">&#41;</span>
		<span style="color: #009900;">&#123;</span>
			<span style="color: #000088;">$_v</span><span style="color: #009900;">&#91;</span><span style="color: #000088;">$k</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">=!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/^&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$p</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;$/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$_v1</span><span style="color: #009900;">&#41;</span>?<span style="color: #0000ff;">''</span><span style="color: #339933;">:</span><span style="color: #000088;">$_v1</span><span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>
		<span style="color: #b1b100;">return</span>  <span style="color: #000088;">$_v</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/^&quot;</span><span style="color: #339933;">.</span><span style="color: #000088;">$p</span><span style="color: #339933;">.</span><span style="color: #0000ff;">&quot;$/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$v</span><span style="color: #009900;">&#41;</span>?<span style="color: #0000ff;">''</span><span style="color: #339933;">:</span><span style="color: #000088;">$v</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</blockquote>
<p>测试：var_dump(input_get(&#8216;a&#8217;,'\d+&#8217;),input_get(&#8216;b&#8217;,'\d+&#8217;));&nbsp; 读取a,b参数，都为数字的！ </p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image2.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="web应用安全参数检测方法" border="0" alt="web应用安全参数检测方法" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb2.png" width="881" height="372"></a> </pre>
<pre>因为参数b输入是：2ccc，因此不是0-9字符。所以返回为空字符串！</pre>
</blockquote>
<p>上面这样每次输入正则表达式确实很麻烦的，其实，一个应用，业务字段，应该都比较固定，我们可以再在该基础上面，进一步封装些，取独立业务字段函数。如：input_getUser($k) 专门读取用户名，input_getQQ($k)专门读取QQ号。如此类推，然后我们发现真的需要独立写检测的变得非常少了！</p>
<p><strong>怎么样限制中文字符？</strong></p>
<p>我有一个真实姓名框，需要输入真实姓名！我该怎么样检测？我们知道常见中文字符表是gb2312，其实中国人取名字现在都需要在常见汉字里面挑选。也就是在区位码表中找。所以，我们问题就变成了，怎么样检查用户输入是不是在gb2312字符集中。gb2312是多字节的，一个中文都是2个字节。只要我们先对好范围就可以了。 gb2312字符集表，我们可以查看：<a title="gb2312字符集、编码表" href="http://doc.chacuo.net/gb2312" target="_blank">http://doc.chacuo.net/gb2312</a> ，</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image3.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="gb2312字符集" border="0" alt="gb2312字符集" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb3.png" width="887" height="559"></a> </pre>
<p>第一个字节范围是：A1-F7 第2个字节范围是A1-FE ，因此我们正则表达式可以写成：[\xA1-\xF7][\xA1-\xFE] 就可以对2个字节限制了。 “怎么拿过去用不了?”，这里我们做中文限制，只完成第一步，在指定字符集中，找好需要用到中文的字符编码。第二步，就是你要将原字符串转码为该字符集编码。如：你如果是utf-8编码，你需要将获取字符串先转码为gb2312，然后再用gb2312字符位置 正则表达式来检测！ 如果，你不转码，你发现刚刚找的那个字符位置正则表达式毫无用处了！通过这个，我们注意做中文位置检测时注意：</p>
<p>1、选择好字符集，找好字符位置，准备好字符范围的正则表达式</p>
<p>2、将待检测字符串，转码为选号的字符集的编码</p>
</blockquote>
<p>现在，我们知道了字符串检测方法了，无论简单参数、还是复杂中文字符参数！我们都可以轻松完成了！通过字符串中字符范围定位需要字符在实际检测中，非常安全！ 因为，很多经常出现问题字符，都不会出现在应用的参数中！只要我们保证第一个关卡，只允许包含业务相关的字符的字符串进入！应用安全，基本上没有问题！好了，就到这里吧！欢迎朋友们发表自己观点！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/360.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTML Link标签 文档资源、导航、SEO 介绍</title>
		<link>http://blog.chacuo.net/339.html</link>
		<comments>http://blog.chacuo.net/339.html#comments</comments>
		<pubDate>Mon, 15 Jul 2013 08:12:59 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[html标签]]></category>
		<category><![CDATA[link]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=339</guid>
		<description><![CDATA[定义和用法 head头标签里面，有另一个不起眼的标签。那就是：Link标签。&#60;link&#62; 标签的作 [...]]]></description>
				<content:encoded><![CDATA[<p><strong>定义和用法</strong></p>
<p>head头标签里面，有另一个不起眼的标签。那就是：Link标签。&lt;link&gt; 标签的作用是定义文档与外部资源的关系，最常用的是链接样式表。</p>
<blockquote><pre></pre>
<p></p>
<pre>&lt;head&gt;
<code>&lt;link rel="stylesheet" type="text/css" href="header.css" /&gt;</code>
&lt;/head&gt;</pre>
</blockquote>
<pre>以上是链接样式表，这是常用的方法。其实它还可以做文件导航、以及seo方面都可以有用途。我们继续往下吧！</pre>
</p>
<p><strong>Link属性介绍</strong></p>
<blockquote>
<table class="table" border="1" rules="all" cellspacing="0" width="98%" frame="box">
<thead>
<tr valign="top">
<th width="20%">属性</th>
<th width="40%">值</th>
<th width="40%">描述</th>
</tr>
</thead>
<tbody>
<tr valign="top">
<td>rel</td>
<td>alternate<br />appendix<br />bookmark<br />chapter<br />contents<br />copyright<br />glossary<br />help<br />home<br />index<br />next<br />prev<br />section<br />start<br />stylesheet<br />subsection<br />icon (后来补充)</td>
<td>定义当前文档与被链接文档之间的关系</td>
</tr>
<tr valign="top">
<td>rev</td>
<td>alternate<br />appendix<br />bookmark<br />chapter<br />contents<br />copyright<br />glossary<br />help<br />home<br />index<br />next<br />prev<br />section<br />start<br />stylesheet<br />subsection</td>
<td>定义被链接文档与当前文档之间的关系</td>
</tr>
<tr valign="top">
<td>href</td>
<td>URL地址</td>
<td>定义被链接文档的位置</td>
</tr>
<tr valign="top">
<td>type</td>
<td>定义媒体类型 MIME_TYPE</td>
<td>指定被链接文档的 MIME 类型</td>
</tr>
<tr valign="top">
<td>media</td>
<td>screen<br />tty<br />tv<br />projection<br />handheld<br />print<br />braille<br />aural<br />all</td>
<td>规定被链接文档将显示在什么设备上</td>
</tr>
<tr valign="top">
<td>charset</td>
<td>字符编码如：utf-8,gb213等</td>
<td>指定被链接文档的字符编码方式</td>
</tr>
<tr valign="top">
<td>hreflang</td>
<td>语言2字代码 <i>language_code</i></td>
<td>指定被链接文档中文本的语言</td>
</tr>
</tbody>
</table>
</blockquote>
<p><strong>其它标准属性：</strong></p>
<blockquote>
<p>1、核心属性 (id,class,style,title)&nbsp; 分别是id号，样式名称，单行样式，title描述</p>
<p>2、语言属性(dir,lang,xml:lang)&nbsp; 分别是 文本方向、语言</p>
<p>3、键盘属性(accesskey,tabindex) 分别是 快捷键、tab建索引</p>
<p>以上属性也具有!</p>
</blockquote>
<p>&nbsp;</p>
<p><strong>SEO相关的使用属性</strong></p>
<p>1、canonical属性值</p>
<p>当一个站点，有几个内容一致的页面（相同内容，有多个url地址），这样页面多的出现、会因为大量重复内容出现，被搜索引擎降权！因此，我们可以利用该属性指定页面出处！</p>
<p>如：http://blog.chacuo.net/332.html&nbsp;&nbsp;&nbsp; http://blog.chacuo.net/?p=332</p>
<p>两个是同一个内容，那么我在http://blog.chacuo.net/?p=332 加入：&lt;link rel=&#8217;canonical&#8217; href=&#8217;http://blog.chacuo.net/332.html&#8217; /&gt;<br />告诉，搜索引擎，这个页面与322.html一致，以322.html为准，不要收录p=322页面。</p>
<p>2、next,prev,home等属性值，带连接的导航作用</p>
<p>例如：当前页是332.html，里面有：</p>
<p>&lt;link rel=&#8217;prev&#8217;&nbsp;&nbsp; href=&#8217;http://blog.chacuo.net/331.html&#8217; /&gt;&nbsp; &lt;link rel=&#8217;next&#8217;&nbsp;&nbsp; href=&#8217;http://blog.chacuo.net/333.html&#8217; /&gt;它相关的上一个页面是331.html，下一个页面是333.html。不过，目前搜索引擎对这些支持不是很好！基本作用不大！</p>
<p><strong>小结：</strong></p>
<p>link，rel属性有多种，现在也有新的扩展，例如wordpress中，我们可以看到：EditURI,wlwmanifest属性。我们也可以自己定义新的属性，不过已经确定了名称属性。它的作用已经固定，我们得遵守它的本意！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/339.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>meta标签 使用说明（http-equiv、refresh、seo）</title>
		<link>http://blog.chacuo.net/332.html</link>
		<comments>http://blog.chacuo.net/332.html#comments</comments>
		<pubDate>Thu, 11 Jul 2013 11:57:45 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[html标签]]></category>
		<category><![CDATA[meta]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=332</guid>
		<description><![CDATA[meta标签，是在head标签里面，一般用做页面描述的。它的内容，用来描述页面一些信息的，如类型、编码、作者、 [...]]]></description>
				<content:encoded><![CDATA[<p>meta标签，是在head标签里面，一般用做页面描述的。它的内容，用来描述页面一些信息的，如类型、编码、作者、简介等！虽然，它不作为页面布局显示，但实际上用途非常广的！具体的html定义在：<a href="http://www.w3.org/TR/html401/struct/global.html#h-7.4.4" target="_blank">meta定义</a>&#160;</p>
<p> <strong>meta组成部分</strong>
<p>meta标签共有两个属性，它们分别是http-equiv属性和name属性，不同的属性又有不同的参数值，这些不同的参数值就实现了不同的网页功能。</p>
<blockquote><p>name属性主要用于描述网页，与之对应的属性值为content，content中的内容主要是便于搜索引擎机器人查找信息和分类信息用的。</p>
<p>http-equiv相当于http的文件头作用，它可以向浏览器传回一些有用的信息，以帮助正确和精确地显示网页内容，与之对应的属性值为content，content中的内容其实就是各个参数的变量值。</p>
</blockquote>
<p> <strong>Meta标签属性</strong><br />
<blockquote>
<table class="table" border="1" rules="all" cellspacing="0" width="98%" frame="box">
<thead>
<tr valign="top">
<th width="20%">属性</th>
<th width="40%">值</th>
<th width="40%">描述</th>
</tr>
</thead>
<tbody>
<tr valign="top">
<td>http-equiv</td>
<td>content-type            <br />Content-Language             <br />Pragma             <br />expires             <br />refresh             <br />set-cookie </td>
<td>把 content 属性关联到 HTTP 头部。http协议返回头，都支持！</td>
</tr>
<tr valign="top">
<td>name</td>
<td>author            <br />description             <br />keywords             <br />generator             <br />revised             <br />others </td>
<td>把 content 属性关联到具体属性的值</td>
</tr>
<tr valign="top">
<td>content</td>
<td>对应（name,http_equiv）选择属性的值</td>
<td>定义与 http-equiv 或 name 属性相关的元信息。</td>
</tr>
</tbody>
</table>
</blockquote>
<p> <strong>http-equiv response返回头控制</strong>
<p>常用来说明页面类型、编码，重定向，以及缓存控制方面！ </p>
<blockquote><p>1、Content-Type和Content-Language (显示字符集的设定)      </p>
<p>&lt;meta http-equiv=″content-Type″ content=″text/html; charset=gb2312″&gt;，当前页面是text/html类型，页面编码是gb2312，也可以简写为&lt;meta charset=&quot;gb2312&quot;&gt;，语言控制：&lt;meta http-equiv=&quot;Content-Language&quot; content=&quot;zh-cn&quot; /&gt; ，说明该页面是简体中文</p>
</p>
<p>2、refresh 自动刷新并且指向新页面      </p>
<p>&lt;meta http-equiv=″refresh″ content=″2; URL=http://blog.chacuo.net″&gt;，2秒后，页面自动进入<a href="http://blog.chacuo.net">http://blog.chacuo.net</a></p>
</p>
<p>3、Expires（过期控制）      </p>
<p>&lt;meta http-equiv=&quot;expires&quot; content=&quot;Fri,12 Jan 2001 18:18:18 GMT&quot;&gt;，可以用于设定网页的到期时间。一旦网页过期，本地缓存将失效，必须重新从服务器读取信息！</p>
</p>
<p>4、Pragma(控制缓存模式） </p>
<p>禁止浏览器从本地计算机的缓存中访问页面内容，&lt;meta http-equiv=&quot;Pragma&quot; content=&quot;no-cache&quot;&gt; 。本地浏览器不保存内容！禁止缓存可以加上：&lt;meta http-equiv=&quot;Cache-Control&quot; CONTENT=&quot;no-cache&quot;&gt; ，这样一起控制！</p>
</p>
<p>5、set-cookie（设置cookie值）      </p>
<p>用法：&lt;meta http-equiv=&quot;Set-Cookie&quot; content=&quot;kkk=ddd; expires=Thu, 11-Jul-23 11:32:15 GMT; path=/; &quot;&gt; 设置cookie，名称是kkk，值为ddd,过期是2023-7-11 19:32:15秒！      </p>
</p>
</blockquote>
<p> <strong>帮助主页被各大搜索引擎登录、其它</strong><br />
<blockquote>
<p>1、Keywords 描述页面关键词      </p>
<p>&lt;meta name=&quot;keywords&quot; content=&quot;政治，经济，科技，文化，卫生，情感，心灵，娱乐，生活，社会，企业，交通&quot;&gt; ，便于搜索引擎，快速定位页面主题！</p>
</p>
<p>2、Description页面简介描述信息      </p>
<p>&lt;meta name=&quot;description&quot; content=&quot;程默博客是一个关注web安全、性能、框架，以及服务器性能、服务器架构、服务器安全,是一个值得Web开发朋友收藏的博客。&quot;/&gt; ，对页面简单描述概括！</p>
</p>
<p>3、Author页面所有者      </p>
<p>&lt;META name=&quot;author&quot; content=&quot;chengmo&quot;&gt; 该页面作者是：<a href="http://blog.chacuo.net/" target="_blank">chengmo</a></p>
</p>
<p>4、Copyright 版权说明      </p>
<p>&lt;META name=&quot;copyright&quot; content=&quot;&amp;copy; 2013 chacuo.net&quot;&gt; 版权信息描述！</p>
</p>
<p>5、Date 开创时间      </p>
<p>&lt;META name=&quot;date&quot; content=”2013-7-11T19:49:37+00:00”&gt;页面开创时间！</p>
</p>
<p>6、robots（机器人向导）      </p>
<p>说明：robots用来告诉搜索机器人哪些页面需要索引，哪些页面不需要索引。content的参数有all,none,index,noindex,follow,nofollow。默认是all。举例：&lt;meta name=&quot;robots&quot; content=&quot;none&quot;&gt;不索引该页，并且该页里面所有连接也不搜索索引！</p>
<p> 
</p>
</blockquote>
<p>以上是meta常见应用，可以对页面进行信息描述，也可以对搜索引擎进行引导！特别是它的属性及值，没有进一步的定义。随着不断应用，可能在后面我们还会扩展出新的属性，以及它对应值！它为今后的扩展预留很多的空间！也有些浏览器，还支持：进入、退出动画，窗口定义，分级定义。不过它不能很好在所有浏览器中兼容，一次没有一一列举！欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/332.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web应用安全之基础（输入参数检查必要性）</title>
		<link>http://blog.chacuo.net/331.html</link>
		<comments>http://blog.chacuo.net/331.html#comments</comments>
		<pubDate>Wed, 10 Jul 2013 11:51:49 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[参数检查]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=331</guid>
		<description><![CDATA[好几天没有写了，电脑一直有问题，还没有修好！本来开机故障，修理了下！现在是彻底开机不了！算了，随它去吧，该换个 [...]]]></description>
				<content:encoded><![CDATA[<p>好几天没有写了，电脑一直有问题，还没有修好！本来开机故障，修理了下！现在是彻底开机不了！算了，随它去吧，该换个品牌了！先不说这些，我们进入正题，看看web应用安全基数，为什么是输入参数检查！开发web应用，工作中代码审核、漏洞修复！基本是我们对输入参数检查不够！</p>
<blockquote><p><strong>主要问题出现在3个方面：</strong></p>
<p>1、对检查认识不够！经常忘记必要参数检测，特别对于一些页面只是传值，而没有写入到后端存储的参数，更是很容易遗漏！</p>
<p>2、对那些是输入的、那些是系统环境参数 有些没有明白，导致错误的放过该检查的参数！</p>
<p>3、检查方法不正确、往往检查过后，还存在问题！ </p>
</blockquote>
<p>&#160;</p>
<p>我说说自己的一些看法吧，所有一切首先要认识到参数检查的重要性！</p>
<p><strong>为什么要参数检查？</strong></p>
<p>我们还是从生活中来看吧，现在社会上，下班回家进入小区，门口保安要检查门卡，有卡才可以进入！到公司了，进门禁系统，公司需要刷员工卡，然后进入公司！现在学校、机关等等，我们发现都会有个检查的，大家都很清楚，它的目的是保证大家安全，让一些自己允许的人才可以进入！我们发现，所有检查地点，都是在分界隔离地方，也就是在进入的入口上！</p>
<p>从上面这些场景，我们发现生活中，为了我们安全！在进入一些私人区域，都有检查口。其实web检查也是可以比拟的！web参数是最前端用户与系统接口地方，因此这个地方检查是必要的！我们只能允许满足要求的进入后端系统！这也是保证后端系统安全的前提！</p>
<p><strong>漏掉该检查地方隐患！</strong></p>
<p>这个问题，同样存在！前段时间，听到一个新闻，一个很高档的小区有很好的安全门禁检查！但是，它的地下车库到楼上，就没有增加检查！后来，一些别有用心的人，专门租车，从地下车库上到居民楼，进行偷盗！还有个新闻，一个小区进门地方，如果是单人的话，会检查，但是如果你开车进入，特别是名牌车！基本上不检查！后来，也导致一伙别有用心的人，驾车进入偷盗！我们做web应用，一定要知道那些参数来源于用户端输入，php代码里面的：$_GET,$_POST,$_REQUEST,$_SERVER,$_COOKIE,$_FILES等。那些来自用户，那些是系统！清清楚楚，明明白白检查！</p>
<p><strong>怎么样检查才正确？</strong></p>
<p>这些我们也可以看看现实生活中，我们发现公司、小区、学校，每个进入的人，都要有一张发的卡，只有持卡人才可以进入！这个是限定用户范围的，只有限定范围才可以进入！这种检查方法，很常用的，也很安全！换个思路，如果小区里面，认为自己小区高档，来小区的都穿着不错。因此，把检查改为：穿正装可以进入！这样一来，如果刚好小区里面有人因为某种原因，而穿着匆忙，可能不让进入！而另外，对于别有用心的人，买套正式衣服应该很容易！因此，也很容易逃过检查！</p>
<p>从上面两个例子我们不难发现，生活中经常检测是：通过发卡，限定用户群；而少用排除法方法！这也是，我们web参数检查中推荐的方法，限定参数的范围；不做、少做参数过滤替换检查！</p>
<p>好了，上面这些方法其实都来自生活，大家一看都明白！如果真的遇到做参数检查时候，有些迷糊！不妨想想生活中例子！其实，程序都是解决实际生活中问题，并且很多都来自于生活！参数需要检查、并且需要正确检查！下一节我将，谈谈对于参数检查范围检查的一些自己看法！欢迎大家交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/331.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式性能优化（高效正则表达式书写）</title>
		<link>http://blog.chacuo.net/329.html</link>
		<comments>http://blog.chacuo.net/329.html#comments</comments>
		<pubDate>Thu, 04 Jul 2013 09:25:59 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[web性能]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=329</guid>
		<description><![CDATA[这里说的正则表达式优化，主要是针对目前常用的NFA模式正则表达式，详细可以参考：正则表达式匹配解析过程探讨分析 [...]]]></description>
				<content:encoded><![CDATA[<p>这里说的正则表达式优化，主要是针对目前常用的NFA模式正则表达式，详细可以参考：<a href="http://blog.chacuo.net/255.html">正则表达式匹配解析过程探讨分析（正则表达式匹配原理）</a>。从上面例子，我们可以推断出，影响NFA类正则表达式（常见语言：GNU Emacs,Java,ergp,less,more,.NET语言,     <br />PCRE library,Perl,PHP,Python,Ruby,sed,vi )其实主要是它的“回溯”，<u>减少“回溯”次数（减少循环查找同一个字符次数），是提高性能的主要方法。 </u>我们来看个例子：</p>
<blockquote><p><font style="background-color: #ffffff" face="Arial">源字符串：&lt;script type=&quot;text/javascript&quot;&gt;adsfadfsdasfsdafdsfsadfsa&lt;/script&gt;</font></p>
<p><font style="background-color: #ffffff" face="Arial">匹配要求，匹配&lt;script….&gt;….&lt;/script&gt;标签里面所有内容，包括改标签</font></p>
<p><font style="background-color: #ffffff" face="Arial"><strong>常见写法(1)</strong>，因为&lt;script后面可能出现字符、空白、特殊符号等，还有标签里面也可能出现各种js代码。我们简单方法是：</font></p>
<p>正则表达式：&lt;script.*?&gt;.*?&lt;/script&gt; (测试工具使用了：<a title="regexBuddy介绍" href="http://blog.chacuo.net/238.html" rel="regexBuddy介绍" target="_blank">regexBuddy</a>)</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式性能优化" border="0" alt="正则表达式性能优化" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb.png" width="821" height="699" /></a> </pre>
<pre><font color="#0000ff"><u>总共花费115步，回溯了：48次。 </u>因为我们使用”.”字符，匹配默认情况下除了\n之外所有字符。</font></pre>
<p><strong>方法（2）</strong>，我们分析特点发现，&lt;script…&gt;后面，应该是除了”&gt;”之外都可以字符，然后一对&lt;script&gt;标签里面js内容。可以定义为除了”&lt;”之外。（<font color="#0000ff">这里面我只是举例说明优化方法，实际网页中script标签里面，常见都会出现有”&lt;”字符了</font>）</p>
<p>正则表达式：&lt;script[^?&gt;]+&gt;[^&lt;]+&lt;/script&gt;</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/07/image1.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式性能优化" border="0" alt="正则表达式性能优化" src="http://blog.chacuo.net/wp-content/uploads/2013/07/image_thumb1.png" width="808" height="581" /></a> </pre>
<pre><font color="#0000ff"><u>19步，0次回溯！ </u>，步骤只有原先的15%左右，性能几倍的提升了！</font></pre>
</blockquote>
<p>从上面我们看到，不同正则表达式，对通用字符配平，性能相差会很大。减少“回溯”是最好的方法，减少回溯其中最主要的方法是：”用最小范围的元字符，尽量避免用过大的元字符！”。一般规律如下：</p>
<p>1、使用正确的边界匹配器（^、$、\b、\B等），限定搜索字符串位置</p>
<p>2、使用具体的元字符、字符类（\d、\w、\s等） ，少用”.”字符</p>
<p>3、使用正确的量词（+、*、?、{n,m}），如果能够限定长度，匹配最佳</p>
<p>4、使用非捕获组、原子组，减少没有必要的字匹配捕获用(?:) </p>
<p>如：我想匹配一些英文字母，它后面接的是数字。如：abc1234,我可以写 “\w+\d+”，也可以写”[a-zA-Z]+\d+” ，其中第一个\w+会先匹配所有abc1234，然后回溯，匹配满足\d+格式。一共4步，而后面这个只需要2步，步骤减少一半了！好了，今天就先到这里，欢迎大家讨论、交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/329.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>京东商城Jsonp 资源越权限访问漏洞分析</title>
		<link>http://blog.chacuo.net/323.html</link>
		<comments>http://blog.chacuo.net/323.html#comments</comments>
		<pubDate>Fri, 28 Jun 2013 10:55:34 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[JSONP]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=323</guid>
		<description><![CDATA[最近比较忙，电脑一直有问题，还没有修理好。本来以前买个电脑才3000来块，现在刚好过保几个月，然后修下说要70 [...]]]></description>
				<content:encoded><![CDATA[<p>最近比较忙，电脑一直有问题，还没有修理好。本来以前买个电脑才3000来块，现在刚好过保几个月，然后修下说要700多，如果换配件要1000多。这个电脑现在买个新二手，应该也就千把块，够黑了。呵呵，不说这么些了。今天我们继续分析京东商城Jsonp使用漏洞之二，未对资源访问进行授权。</p>
<p>对于Jsonp漏洞，这里我就不细说了，详细可以看：<a href="http://blog.chacuo.net/295.html">Jsonp常见安全漏洞分析(京东商城Jsonp 漏洞分析)</a> ，从上面文章，我们知道jsonp是可以跨域名调用的。<font color="#0000ff"><u>这个漏洞是：没有授权网站，可以直接在该站点访问jsonp接口资源。</u></font><font color="#000000">可能有朋友会问题：“这个漏洞有什么影响呢？”，一般我们常见有：</font></p>
<blockquote><p><font style="background-color: #ffffff" face="Arial">1.对于存在漏洞的网站来说：jsonp资源给外部调用，浪费接口资源，也给调用带来压力</font></p>
<p><font style="background-color: #ffffff" face="Arial">2.利用者，可以通过jsonp获取网站资源，构造钓鱼站点，或者给用户发送钓鱼站点。获取用户在漏洞网站上面的用户信息（用户登陆情况下），或者偷偷操作用户功能！</font></p>
</blockquote>
<p><strong>具体我们看看实例：</strong></p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image45.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="京东商城jsonp漏洞" border="0" alt="京东商城jsonp漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb45.png" width="854" height="297" /></a> </pre>
<pre>我们看看，如果有个另外域名站点，怎么样调用该信息！</pre>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-Type: text/html; charset=utf-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">?&gt;</span>
&lt;script&gt;
function jsonp13724(d)
{
	console.log(d);
}
&lt;/script&gt;
&lt;script type=&quot;text/javascript&quot; src=&quot;http://my.jd.com/order/rec.action?jsoncallback=jsonp13724&quot;&gt;
&lt;/script&gt;</pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image46.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="京东商城jsonp漏洞" border="0" alt="京东商城jsonp漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb46.png" width="853" height="514" /></a> </pre>
<pre>&#160;</pre>
</blockquote>
<p>总结，通过上面例子，对于jsonp跨站访问，带来资源别越权调用漏洞。我们应该知道了它的原理。如果要防止这类越权访问，我们一般只需要对<u><font color="#0000ff">访问来源：reffer进行授权 </font></u>这是最简单的方法！ 也是最常用方法了。如果有朋友会问，这个漏洞有什么危害呀，看起来好像没有什么问题？如果一个站点别有用心站点(这里叫A站)，在京东商城上面发了一个链接。有不小心朋友点过去。这个时候，你刚好自己登陆了。这个时候，A站就可以悄悄读到你在京东商城一些信息了。到此，对京东商城jsonp漏洞都分析完毕，国内这么大一个商城，在这个方面使用，几乎没有做任何检测，确实有些不应该！希望，以上分析对即将应用jsonp朋友有所帮助！也需要大家发表自己看法！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/323.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GBK字符编码（字符集）缺陷攻击（注入）原理</title>
		<link>http://blog.chacuo.net/312.html</link>
		<comments>http://blog.chacuo.net/312.html#comments</comments>
		<pubDate>Mon, 24 Jun 2013 09:38:08 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[GBK缺陷]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=312</guid>
		<description><![CDATA[上一节，我们分析了。选择不同编码可能会导致程序带来本身潜在的漏洞。这次我们以GBK编码为例，看看怎么样通过该编 [...]]]></description>
				<content:encoded><![CDATA[<p>上一节，我们分析了。选择不同编码可能会导致程序带来本身潜在的漏洞。这次我们以GBK编码为例，看看怎么样通过该编码注入到系统中。目前很多开源系统都存在类似的注入问题。我们先来，从一个Demo开始！</p>
<p><strong>GBK字符集漏洞注入原理</strong></p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$u</span><span style="color: #339933;">=</span><span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'u'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>? <span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'u'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$u</span><span style="color: #339933;">=</span><span style="color: #990000;">addslashes</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$u</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000088;">$sql</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;select * from user where user='<span style="color: #006699; font-weight: bold;">$u</span>'&quot;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>以上是我们写的一个测试例子（GBK编码），现在很多开源系统，比较少的进行统一参数过滤，有时候为了防止注入，就直接对参数进行转义处理。我们看看，这样一个例子，我们怎么样注入进系统！</p>
</blockquote>
<blockquote>
<table class="table" border="1" rules="all" cellspacing="0" width="820" frame="box">
<thead>
<tr valign="top">
<th width="316">步骤</th>
<th width="617">备注</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="316">1.传入值%D5%27 or 1=1#</td>
<td valign="top" width="617">u参数参入上面值 (%27 对应是“’”&#160; 单引号字符)</td>
</tr>
<tr>
<td valign="top" width="316">2.GET获取的值</td>
<td valign="top" width="617">0xD50x27 or 1=1# </td>
</tr>
<tr>
<td valign="top" width="316">3.Addslashes后值</td>
<td valign="top" width="617">0xD50x5C0x27 or 1=1 (意思是：誠’ or 1=1#’)&#160; #字符后面被注释掉</td>
</tr>
<tr>
<td valign="top" width="316">4.sql值 将变成</td>
<td valign="top" width="617">select * from user where user=’誠’ or 1=1#’</td>
</tr>
<tr>
<td valign="top" colspan="2">#号是sql注释符号，后面字符将截取掉</td>
</tr>
</tbody>
</table>
<pre>&#160;</pre>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image44.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="GBK编码漏洞注入测试" border="0" alt="GBK编码漏洞注入测试" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb44.png" width="821" height="280" /></a> </pre>
</blockquote>
<p>GPC转义打开，或者是通过addslashes函数，会自动在字符是单引号（<i>&#8216;</i>）、双引号（<i>&quot;</i>）、反斜线（<i>\</i>）与 NUL（<b><tt>NULL</tt></b> 字符）等字符前面增加“\”字符（0x5c)，例子里面，我们采用一个特殊前面字节0xD5，它将与该字节组合变成：0xD50x5c ，刚好是gbk字符集中字符：”誠“ 了。 后面的0&#215;27这个单引号被保留下来了！</p>
<p><strong>GBK字符集漏洞注入总结</strong></p>
<p>呵呵，这个很有意思吧，好了。我们来总结下，这类注入是2个条件的。<u><font color="#0000ff">第一是：gbk编码，第二是：程序采用了转义方法，转义了输入。</font></u> 这2个条件不苛刻，目前大部分开源系统都有gbk,utf-8编码的源码，剩下的就去看看，源码里面有没有用类似转义方法，过滤字符串了。如果有，那么这个系统某个功能，你可以去渗透下了。这个编码漏洞，网上面提的很多，不过很多时候，没有引起开发人员的足够重视，还是在不断的重现！</p>
<p>那么我们如果要注入一个参数，我们该选择什么样的入参参数呢？其实这种转义字符是单引号（<i>&#8216;</i>）、双引号（<i>&quot;</i>）、反斜线（<i>\</i>）与 NUL（<b><tt>NULL</tt></b> 字符），我们这些字符往往在程序中有特殊作用，我们只需要在前面加<strong><font color="#0000ff"><u>一个在&gt;7F字符，后面接一个%27（<i>&#8216;</i>）、%22（<i>&quot;</i>）、%5C（<i>\</i>）、%00（<tt>NULL</tt> 字符）</u></font></strong>，就可以自己让这4个字符，可以逃脱转义了。</p>
<p>好了，这个漏洞原理及注入过程分析就这些了。我们开发时候，需要注意这个问题，特别是使用GBK编码开发程序，要有这个方面的预备知识，对于自己开发安全的代码会有帮助的。更多的<a title="GBK字符集" href="http://doc.chacuo.net/gbk" rel="GBK字符集" target="_blank">GBK编码</a>，可以看<a href="http://doc.chacuo.net/gbk">http://doc.chacuo.net/gbk</a> ！（这里有很多落在5c中文字符呢）也欢迎讨论！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/312.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GBK字符编码（字符集）缺陷导致web安全漏洞</title>
		<link>http://blog.chacuo.net/309.html</link>
		<comments>http://blog.chacuo.net/309.html#comments</comments>
		<pubDate>Fri, 21 Jun 2013 09:21:34 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[web安全]]></category>
		<category><![CDATA[GBK缺陷]]></category>
		<category><![CDATA[字符编码]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=309</guid>
		<description><![CDATA[很多时候，一个web站点，选择什么样的字符编码，我们不会太过在意的。象中文网站，我们一般用gb2312,gbk [...]]]></description>
				<content:encoded><![CDATA[<p>很多时候，一个web站点，选择什么样的字符编码，我们不会太过在意的。象中文网站，我们一般用gb2312,gbk,gb18030,也可以用utf-8。但是，可能我们不知道，选择不同编码，可能因此导致程序本身设计缺陷。</p>
<p><strong>多字节编码由来</strong></p>
<p>我们先来看看最常用的，最小字符集是ascii，对应的二级制可以表示为：00-7F 编码 。它也是我们计算机使用最早通用的字符集。前期几乎可以表示所有英文字符。后来，更多使用计算机国家加入后，我们就想在计算机中表示中文字符。我们知道常见中文就有7000多个字符。ascii码就只有128字符，只有0-127编码位置，远远不够用了。因此，我们就开始制作更大字符集，并且保证兼容ascii编码。要支持更多字符，选择更大字符集。我们只能用多个字节来描述一个字符了。为了很好的与ascii码，区分开来！一般做法是：每个字节值都大于&gt;7F，如果是2个字节，那么就是：[&gt;7F][&gt;7F]。这样编码，保证很好的与ascii区分开，并且扩大了字符集。像gb2312范围在[0xA1-0xF7][0xA1-0xFE](中间很多没有填满)，它完全保证所有字节在A0之上，也就完全满足在7F之上了。</p>
<p><strong>GBK编码漏洞缘由</strong></p>
<p>通过上面的分析，我们知道gb2312编码是很好的跟ascii码分开了。 那么我们看看，GBK编码呢，它是完全兼容gb2312（就是说在gb2312字符集中每个字符位置，与gbk字符集里面位置完全一致，而且包含于gb2312)，但是，它有2万多个字符。从上面看，只能选择往下排序了。 就是从A1A0往下排了，我们发现它编码实际范围是：[0x81-0xFE]([0x40-0x7E|0x80-0xFE] ) （<a title="gbk字符集" href="http://doc.chacuo.net/gbk" rel="gbk字符集" target="_blank">GBK编码</a>），我们发现由2个字节组成，首字节范围在7F之上，而第2个字节，有一部分在0&#215;40-0x7E了。这就是导致bug原因。我们看看下面例子吧！</p>
<blockquote><p><font style="background-color: #ffffff" face="Arial">从ASCII码表中，我们知道0&#215;40-0x7E 包含字符有：“<a href="mailto:&ldquo;A-Za-z@[\">A-Za-z@[\</a>]^_`{|}~”，一共有63字符呢。</font></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image43.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="GBK编码漏洞" border="0" alt="GBK编码漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb43.png" width="574" height="251" /></a> </pre>
<p>选择gbk编码，运行上面代码，就一条简单的命令导致出现错误，说字符串 赋值 没有结束！ 呵呵，估计很多人看到这个就会认为是php 出Bug了。但是，如果我们变成$a=”誠a”，发现可以正常运行了。是不是觉得很奇葩啦！！</p>
<p>&#160;</p>
</blockquote>
<p>原因分析:我们知道文件存在磁盘都是二级制方式，无论你存什么字符，最终都是以<strong>该字符的在所选字符集中字符编码保存</strong>。php解析时候，最小分析单元是字节。无论你是多字节还是单字节字符。最终都是按照字节来处理的。<font color="#0000ff"><u>“誠”&#160; GBK编码是 D55C，php按字节来解释，5C对应字符是“\” 字符。后面直接跟个‘”’，相当于被转义了。 因为没有闭合，因此出现错误！</u>。</font><font color="#000000">大家看出问题所在了吧，按自己处理的话，会自然把多字节拆成单字节了。这样就会出现很多奇怪问题了。 </font></p>
<p>总结：通过上面讲解，我们知道了多字节编码过程，以及GBK导致简单程序出错的原因。其实，我们很多程序语言里面，都会以单个字节来解析的。这样，当你选择多字节GBK编码中文时，刚好有字节落在特殊位置，将会出现奇怪错误问题。而且，还将给系统带来本身的漏洞，后面我再说说，GBK编码缺陷，导致漏洞、以及专门利用该编码漏洞缺陷进行系统入侵！好了，先到这里了，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/309.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>京东商城Jsonp 漏洞分析 （京东商城XSS漏洞）</title>
		<link>http://blog.chacuo.net/304.html</link>
		<comments>http://blog.chacuo.net/304.html#comments</comments>
		<pubDate>Thu, 20 Jun 2013 07:27:45 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[JSONP]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=304</guid>
		<description><![CDATA[继续我们jsonp 安全使用分享吧！上一篇文章我们提到jsonp使用，常见2种类型漏洞出现！详细可以看看：Js [...]]]></description>
				<content:encoded><![CDATA[<p>继续我们jsonp 安全使用分享吧！上一篇文章我们提到jsonp使用，常见2种类型漏洞出现！详细可以看看：<a href="http://blog.chacuo.net/295.html">Jsonp常见安全漏洞分析</a> ，今天我们来结合实例分析下该漏洞的测试、及利用过程吧！</p>
<p><strong>题外话</strong></p>
<p>为什么我选择是京东商城来分析它的jsonp 漏洞呢，其实主要原因最近6.18一直在做活动，我也买了不少便宜东西。现在该商城越做越好了。它系统也非常庞大，速度性能也很好。当时在购物时候，只是想看看，它的系统分离设计方面。通过分析页面http请求，发现有很多jsonp调用（也许跟换域名有关系，2种域名都可以访问，中间用jsonp交换数据），于是就看看，jsonp常见2种安全方面，有没有做处理。结果一测试。发现完全没有做任何处理，几乎是完完全全暴露出来。个人认为，对于这么大站点，这一点还是头一次遇到！居然，没有任何参数处理、以及资源授权！</p>
<p><strong>京东商城Jsonp xss漏洞分析</strong></p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image40.png"><img style="display: inline; border-width: 0px;" title="京东商城xss漏洞" alt="京东商城xss漏洞" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb40.png" width="853" height="379" border="0" /></a></pre>
<p>我们看到，该请求就是一个jsonp，</p>
<p>默认返回：jsonp13**********({&#8220;Identity&#8221;:{&#8220;Name&#8221;:&#8221;",&#8221;IsAuthenticated&#8221;:false}})，我们知道callback传入参数，会在response中 作为函数调用名称返回！</p></blockquote>
<p><strong>分析callback 字符范围</strong></p>
<blockquote><p><span style="background-color: #ffffff; font-family: Arial;">1、测试下有没有屏蔽常见特殊字符” &lt;&gt; ()&#8217;&#8221;;. {}“，以下这些字符，经常会用到xss里面的。</span></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image41.png"><img style="display: inline; border-width: 0px;" title="京东商城callback没有屏蔽特殊字符" alt="京东商城callback没有屏蔽特殊字符" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb41.png" width="841" height="523" border="0" /></a></pre>
<pre></pre>
</blockquote>
<p>到这里，分析说明这里存在着xss注入漏洞的。而且，可以选择很多种方法注入！ 本编文章，旨在说明jsonp xss漏洞成因！不会具体去扩大漏洞拿到其它什么权限。以下还有个很有意思事情，callback其实，jd对一些特殊字符串做了处理的。我们看看：</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image42.png"><img style="display: inline; border-width: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb42.png" width="832" height="470" border="0" /></a></pre>
<pre></pre>
</blockquote>
<p>从上图中，我们可以看到，京东商城，对输入callback对一些特定的字符串进行了屏蔽处理！这也是，我们做xss漏洞检查时候，经常出现问题。<span style="color: #0000ff;"><span style="text-decoration: underline;">屏蔽字符串能够屏蔽完吗？常见26字符，长度不一任意组合。该有多少字符串呢？ </span></span><span style="color: #000000;">很多朋友，在做安全检测时候，就是屏蔽某些觉得很不安全的标签就认为安全了。 其实，我们发现这样做法只能是一时安全，过不了多久，你会发现又有新的字符串出现。你会为此花费大量的人力物力！</span><span style="color: #0000ff;"><span style="text-decoration: underline;">好了，做类似事情，我们最好方法是，认证那些觉得安全的字符，予以放行！ </span></span></p>
<p>其实，<strong>为什么用白名单方法放行允许的字符呢？ 而不是去过滤一些字符串。</strong>原因刚刚说了，字符串太多了。过滤不过来！另外是，我们自己每个业务参数，会用到那些字符其实我们更清楚。另外有人会问，<strong>为什么不去屏蔽不用的字符呢？</strong>我们知道基础<a title="ascii码" href="http://doc.chacuo.net/ascii" target="_blank" rel="ascii码">ascii码</a>有0-127,128字符。往往我们，不会用到的字符可能更多呢，我们去过滤不会用到字符，有时候更困难！</p>
<p><strong>正确检查jsonp callback方法</strong></p>
<p>建议收到callback函数对它进行白名单字符范围检测！我们可以用一般函数检测规范来检查就可以了。 既然它是一个函数名称，<strong>一般都是字符+数字+下划线+点号（对象分割）。</strong>那么我们检测变得非常简单，代码类似如：</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$callback</span> <span style="color: #339933;">=</span> <span style="color: #990000;">isset</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'callback'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span>?<span style="color: #000088;">$_GET</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">'callback'</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">''</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">!</span><span style="color: #990000;">preg_match</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/^[0-9a-zA-Z_.]+$/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$callback</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'参数错误！'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</blockquote>
<p>后记：以上是分析一个jsonp xss漏洞过程。要检测一个站点是否有该漏洞，其实简单方法，就是看通过参数传入进去的特殊字符，是不是原原本本的response 返回出来。 如果有朋友问我，怎么样利用该漏洞，它能做点什么？ 你可以把它比作一个蚁穴，能带来多大危害，看蚂蚁怎么样啃食啦！这些年，sql注入几乎难找了，不过xss漏洞是头号杀手。只要有xss漏洞出现，几乎可以做到无所不能，就看利用的人怎么用了。 以上漏洞，我反馈京东商城，这么好的一个网站，不能因为这个小小xss，给用户带来大的安全隐患了！最后，欢迎朋友提出自己建议！还有一个忘记说了，就是它的jsonp访问权限完全没有限制，下次再分享吧！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/304.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Jsonp常见安全漏洞分析(京东商城Jsonp 漏洞分析)</title>
		<link>http://blog.chacuo.net/295.html</link>
		<comments>http://blog.chacuo.net/295.html#comments</comments>
		<pubDate>Wed, 19 Jun 2013 08:45:39 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[JSONP]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=295</guid>
		<description><![CDATA[JSONP（JSON with Padding）是资料格式 JSON 的一种“使用模式”，可以让网页从别的网域 [...]]]></description>
				<content:encoded><![CDATA[<p><b>JSONP</b>（<b>JSON with Padding</b>）是资料格式 JSON 的一种“使用模式”，可以让网页从别的网域要资料。这个解释来自于互联网上面的答案。jsonp只是 一种使用json模式，之所以能够很广泛使用。主要用它来解决跨域访问问题。可以方便跨域名传输数据。一些是一个jsonp的例子。但是，正确的使用jsonp是至关重要的，用得不好。将带来重要资料把超范围访问，还会带来各自xss漏洞。</p>
<p><strong>JSONP跨域请求例子</strong></p>
<blockquote><p>传统的ajax ，往往是 XMLHttpRequest ，读取一个接口，返回类似: {&#8220;Name&#8221;: &#8220;小明&#8221;, &#8220;Rank&#8221;: 7} json值。一般我们都采用xmlhttprequest方法通过状态判断执行请求是否完毕。</p>
<p>JSONP的使用模式里，该URL回传的是由自定义传入函数名，动态生成JSON作为该函数入参，这就是JSONP 的“填充（padding）”或是“前辍（prefix）”的由来。</p>
<p>请求：</p>
<pre>&lt;script type="text/javascript"
         src="http://www.example.com/RetrieveUser?UserId=1823&amp;callback=parseResponse"&gt;
     &lt;/script&gt;</pre>
<pre>返回：</pre>
<pre>parseResponse({"Name": "Cheeso", "Id" : 1823, "Rank": 7})</pre>
<pre></pre>
<pre></pre>
</blockquote>
<p>parseResponse是传入参数值决定的，这样好处通过script标签可以解决跨域问题，并且只要script src地址加载完，js解析引擎就开始执行src地址返回 js内容了。 我们使用者不用关心，什么时候src地址加载解析完。只用写好接收函数：parseResponse，到时候自动回执行该项目。比传统ajax确实多了很多方便！目前，象google翻译，地图等都用该方法。实现了跨域及异步调用！</p>
<p><strong>JSONP漏洞将来自哪里？</strong></p>
<p>它给我们带来的发布，是毫无疑问的。那么它将会有哪些漏洞呢？首先，我们知道，<span style="text-decoration: underline;"><span style="color: #0000ff;">一切输入是有害的</span></span>。传入callback 值会在结果里面直接返回。因此，如果该参数过滤不严格。可以随便输入：callback值为：alert(‘1’);parseResponse  字符串。返回结果会打印个alert窗口，然后也会正常执行。</p>
<p>那么另外我们知道，flash是可以跨域的。flash请求外部资源，现在都有个”<em>crossdomain.xml</em>”，可以授权允许那些来源的站点，访问指定站点的资源。其实目的就是为了防止，资源被越权调用了。 如果我们不对其授权，那么任何网站都可通过：创建script标记，读取我网站资源了！这个安全项，也就是是否有对访问来源进行了授权访问！</p>
<p><strong>JSONP漏洞总结：</strong></p>
<p>知道了JSONP漏洞点主要有：callback参数注入、资源访问授权设置！我们其实，可以通过这2项，来检测我们的做的JSONP项目，里面是否有安全隐患了。好了，今天先分析到这里。这些漏洞都是，技术实现型漏洞！只要，我们明白了方法，杜绝是很容易的。之所以会出现类似安全隐患，更多来自，<span style="color: #0000ff;"><span style="text-decoration: underline;">不知道这里有类似安全问题！ </span>，</span><span style="color: #000000;">题外话、发发感慨！！现在网上看到很多教程，以及书籍都只会讲，怎么样使用某个功能，它的方法、技巧等等！很少解决，技术功能点安全避免漏洞的调用方法！</span><span style="color: #0000ff;"><span style="text-decoration: underline;">做一个功能很重要，但是我始终认为，开发一个安全、稳定功能是最基础的前提。 如果做的功能不安全，稳定！它急着上线，只会带来更大的风险、或是损失！！！</span> </span><span style="color: #000000;">  欢迎大家交流，提出更换的建议！（”什么？这里不是说京东商城有JSONP漏洞吗？“  ”对!没错！” 今天我这里分析漏洞点，大家可以找找京东商城这方面使用漏洞，我们下次分享实例！)</span></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/295.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web开发人员 提升技术、突破瓶颈方法探讨</title>
		<link>http://blog.chacuo.net/293.html</link>
		<comments>http://blog.chacuo.net/293.html#comments</comments>
		<pubDate>Tue, 18 Jun 2013 15:18:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[学习心得]]></category>
		<category><![CDATA[突破技术瓶颈]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=293</guid>
		<description><![CDATA[技术瓶颈表现 作为一名web技术开发人员，也是我们说的IT人员。 刚刚入门时候，会发现有很强的兴趣。天天会遇到 [...]]]></description>
				<content:encoded><![CDATA[<p><strong>技术瓶颈表现</strong></p>
<p>作为一名web技术开发人员，也是我们说的IT人员。 刚刚入门时候，会发现有很强的兴趣。天天会遇到新的事情，可以不断做一些新的功能。到后来，会发现。自己所做的工作，技术点都差不多，然后感觉学习东西越来越少。最后，也慢慢对该行业兴趣不强烈了。 而后，慢慢有些油了。 总是感觉学习知识是在炒旧饭，很久也没有感觉到自己的提升。 这个时候，也就是我们经常说的技术瓶颈。</p>
<p><strong>怎么样突破技术瓶颈</strong></p>
<p>我们知道，行行出状元。并且能熟能生巧，那么我们做技术是不是做的多，也自然而然会成为状元，会生巧呢？ 确实，作为web技术人员，做得多，对自己编码速度，处理问题提升会很多。 但是，却又不完全成正比。我们发现很多时候，看似我们做系统技术点工作，但是很少有相同产品。只是技术实现类似而已！作为技术人员，我想主要提升方面是：<u><font color="#9b00d3">技术广度、另外是技术深度</font></u></p>
<p><font color="#000000">技术广度，可以从web人员，学习技能入手。可以看看，前面一篇文章：</font><a title="web开发人员技能点" href="http://blog.chacuo.net/280.html" rel="web开发人员技能点">web前端开发人员技能点汇总、技术详细列表</a>&#160; ，这一般很容易理解，也很容易学习到。基本上是这些功能点而已。 但是，另外技术深度，就很难把握！它像水面有张力一样，一般很难沉下去。这里，我们可以想象下，为什么会这样。</p>
<p>技术深度非常重要。作为一名web开发人员，很多都是通过培训，或者自己感兴趣，然后看看书，去模仿模仿，有人指导下。 然后就是一名web人员了。 但是，所有经验大多数来自实际总结，但是，实际我们缺少了，web开发原理东西。这方面一般很少有朋友喜欢整本整本书看。一般习惯网上看看，别人分享经验技巧。这样一来，对学习只是也是很零碎的。这些都是导致想深入学习的原因。</p>
<p>要深入，我们必须对一个问题，首先是了解它是什么，然后是怎么样使用，最后是为什么它会达到这样结果。也就是我们常说的，刨根问底！很多时候，web人员，喜欢”功能开发完了，就OK了”， 也不会去寻找该功能实现本质，有没有其它更好方法。这样，你将始终停留在使用功能。不停重复使用相同功能。 其实，有人说要做好一名技术人员，必须<font color="#9b00d3"><u>有所追求 </u>，</font><font color="#000000">其实就是需要有刨根问底的精神。要能每次做同一个事情，都有新要求。我的代码结构，性能、安全、扩展性等方面。是不是提升了。这些都可以是具体提升的一些方面。</font></p>
<p>因此，要提升自己技术深度方法。就是，每次再实现一个方法方面，有所创新，有所改进。无论是结构，还是性能，还是安全，还是其它等等方面。你会发现，在改造同时，自己对该项知识掌握就自然深入了。 越来越了解该项技能本质了。 做一个有技术追求的人，是能很好的提升自己的广度、深度的！</p>
<p>好了，以上是我对技术成长方面，广度、深度理解。欢迎朋友有不同方法，可以给予建议！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/293.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式、分组、子匹配（子模式）、非捕获子匹配（子模式）</title>
		<link>http://blog.chacuo.net/289.html</link>
		<comments>http://blog.chacuo.net/289.html#comments</comments>
		<pubDate>Mon, 17 Jun 2013 14:25:25 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=289</guid>
		<description><![CDATA[前面我们知道正则表达式有很多元字符表示匹配次数（量词），都是可以重复匹配前面出现的单个字符次数。有时候，我们可 [...]]]></description>
				<content:encoded><![CDATA[<p>前面我们知道正则表达式有很多元字符表示匹配次数（量词），都是可以重复匹配前面出现的单个字符次数<u><font color="#9b00d3">。有时候，我们可能需要匹配一组多个字符一起出现的次数。这个时候，我们需要分组了。就是用小括号来括起这些字符，指定子表达式(也叫做分组)。</font></u>然后你就可以指定这个子表达式的重复次数了，你也可以对子表达式进行其它一些操作。这个时候，可以把括号中一组字符，看作一个整体了。</p>
<p><strong>分组模式举例说明</strong></p>
<blockquote><pre>如：查找字符串中，连续出现多个win字符串的字符。可以这样完成</pre>
<pre>&#160;</pre>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
&nbsp;
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;this is win winwindows!&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/(win)+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>&#160;</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image36.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式分组" border="0" alt="正则表达式分组" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb36.png" width="789" height="526" /></a></pre>
</blockquote>
<p><strong>不用分组模式，同时匹配多个字符，可以吗？</strong> 我们发现以前操作符号：[win]+，尽管可以匹配到winwin字符，因为它代表是有w,i,n组合的一个或者多个字符，不会限制顺序。所见它会匹配到象：wwin,www,inw等等，只要是这3个字符组成的，多个字符都匹配成功了。</p>
<p>上面怎么匹配到，每一个有2个结果呢？这就是子模式（子匹配），默认除了可以将多个字符组合一个整体，另外还会把括号，括起来的这部分表达式存储到一个临时缓冲区中，以便后面正则表达式调用。上面这个例子里面，我们不需要，后期调用的。因此，怎么样屏蔽掉这个子表达式捕获内容呢？ 只需要在：前加上”?:” 即可。我们看看下面例子<u><font color="#9b00d3">正则表达式 分组非捕获模式</font></u>。</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image37.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式 分组非捕获模式" border="0" alt="正则表达式 分组非捕获模式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb37.png" width="787" height="382" /></a></pre>
<pre>&#160;</pre>
</blockquote>
<p>非捕获模式优点有哪些呢？ 从上面看，可以减少捕获，也就会减少匹配次数。因此，在不必要分组表达式加入非捕获前缀”?:”，可以节省内存开销，并且可以提升匹配速度！</p>
<p>刚刚说到了正则表达式分组，默认情况会将子表达式捕获内容，存储到一个缓存区。以便后续调用。 那这个是什么样情况呢？其实，这个是正则表达式的引用。所捕获的每个子匹配都按照在正则表达式模式中从左至右所遇到的内容按顺序存储。存储子匹配的缓冲区编号从1开始，最多可以一般存储为9。以便后面表达式引用该值，又叫后向引用。</p>
<blockquote>
<pre>我们看下下面例子，查找一个字符串中，互不相邻，出现多次系统单词：add。</pre>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;add123456addasdf&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/(add)\d+\1/'</span><span style="color: #339933;">,</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>&#160;</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image38.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式反向引用" border="0" alt="正则表达式反向引用" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb38.png" width="811" height="437" /></a></pre>
</blockquote>
<p>反向引用，常用来处理一些处理一些特殊匹配情况。如：查找字符串中，不相邻重复字符串。查找html一对标签中内容。特别分析html非常常见了(注意，如果使用了反向引用，前面不能屏蔽子匹配捕获，也就是不能加”?:&quot;前缀了)。经常会用：</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$str</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://blog.chacuo.net/'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'/&lt;(\S+)[^&gt;]*&gt;[^&lt;]*&lt;\/\1&gt;/'</span><span style="color: #339933;">,</span><span style="color: #000088;">$str</span><span style="color: #339933;">,</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$marr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// (\S+) 表示非显示字符之外所有字符，一般作为html tag名称</span>
<span style="color: #666666; font-style: italic;">// tag格式一般为 &lt;tag   其它属性&gt; 后面[^&gt;]* 匹配tag里面所有其它属性</span>
<span style="color: #666666; font-style: italic;">// 后面的[^&lt;]* 表示 &lt;tag...&gt;中间内容&lt;/tag&gt; 表示中间内容，到&quot;&lt;&quot;结束，因此匹配所有[^&lt;]* 字符</span>
<span style="color: #666666; font-style: italic;">// 最后的&lt;\/\1&gt; &quot;\/&quot; 转义&quot;/&quot;字符，后面的&quot;\1&quot; 表示反向应用前面的(\S+)</span></pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image39.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式匹配html标签" border="0" alt="正则表达式匹配html标签" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb39.png" width="833" height="364" /></a></pre>
<p>&#160;</p>
</blockquote>
<p>以上是正则表达式使用比较重要的，分组，反向匹配，以及非捕获分组说明及实例。希望对要属性改功能朋友有所帮助。同时欢迎朋友们交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/289.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>web前端开发人员技能点汇总、技术详细列表</title>
		<link>http://blog.chacuo.net/280.html</link>
		<comments>http://blog.chacuo.net/280.html#comments</comments>
		<pubDate>Sun, 16 Jun 2013 15:16:41 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[学习心得]]></category>
		<category><![CDATA[前端开发技能点]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=280</guid>
		<description><![CDATA[常常做了一段时间的web开发，然后就慢慢迷失了方向。感觉自己的技术到一个瓶颈，不知道下一步该要学习哪些知识。常 [...]]]></description>
				<content:encoded><![CDATA[<p>常常做了一段时间的web开发，然后就慢慢迷失了方向。感觉自己的技术到一个瓶颈，不知道下一步该要学习哪些知识。常常这个时候，很多人因为瓶颈，导致一直原地踏步！也有写朋友，感觉自己什么都可以了。 记得，我当时刚做1年多网站时候。就有那个感觉，觉得自己什么都可以做了。什么留言板、用户系统、论坛、产品管理等，然后去一家大一点的公司谋职，被一个招聘人员问了几个问题。然后，觉得自己非常自信，回答非常好！但是结果音信全无，指导后来过来几年后，对当时那段时间回忆起来，觉得自己当时勇气可嘉！</p>
<p>下面，这个图，是作为web开发人员，技能知识点汇总。里面常常包括，ui人员、js人员、web编码人员的所有知识点。但是，这3者之间开发中联系密切。彼此之间多了解下，很有必要的！</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/fks.jpg"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="web开发人员技能知识点汇总" border="0" alt="web开发人员技能知识点汇总" src="http://blog.chacuo.net/wp-content/uploads/2013/06/fks_thumb.jpg" width="922" height="836"></a></pre>
<pre>本图来源于开源项目：<a href="https://github.com/jacksontian/fks">https://github.com/jacksontian/fks</a>  里面有详细学习资料介绍，大家可以去了解下！</pre>
<pre>&nbsp;</pre>
</blockquote>
<p>从这个图里面，几乎包含了ui,js,web程序开发。这3个方面，无论那个方面人员，我觉得都有必要可以多了解下这些技能点。多了解些技能点，彼此直接沟通会更方便！也将容易得多了。我想，如果很早那年我有看过这个图，我就知道自己有几斤几两啦！（当然，比较早时候，很多知识那个时候还没有出现。不过也至少有这个图里面一半左右知识技能点）</p>
<p><strong>web开发人员技能提升提现</strong></p>
<p>也就是说，怎么样说明自己在进步了，自己确实提高了。我认为有2点重要，上面这个图说的是需要<strong><u>掌握的技能点的广度 ,</u></strong>另外一点就是：<strong><u>掌握技能点的深度 </u></strong>。估计这个时候，我们脑子里面就会想，广度很好理解好验证的。那么深度指的是什么呢，我自己到底掌握到那个深度了呢？下次，我会继续补充！欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/280.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>php header 重定向常出现功能(使用)漏洞</title>
		<link>http://blog.chacuo.net/276.html</link>
		<comments>http://blog.chacuo.net/276.html#comments</comments>
		<pubDate>Sat, 15 Jun 2013 09:45:28 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web安全]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=276</guid>
		<description><![CDATA[php header函数功能强大，可以给用户发送各种header头信息，只要header头里面能够发送的内容， [...]]]></description>
				<content:encoded><![CDATA[<p>php header函数功能强大，可以给用户发送各种header头信息，只要header头里面能够发送的内容，都可以通过header函数来完成。如发送302跳转，设置cookie，发送401认证，发现last-modify等等！ HTTP/1.1 specification for more information on <acronym>HTTP</acronym> headers，都可以用该函数完成。总之一句话，任何服务区response应答的头信息几乎都可以用它来发送。如：</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image34.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="response 服务器响应头" alt="response 服务器响应头" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb34.png" width="572" height="222" border="0" /></a></pre>
</blockquote>
<pre></pre>
<pre>这里我们经常用header发送302跳转，会发现一个问题。在走查代码时候，遇到很多同人会有类似操作代码，如：</pre>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;Content-type: text/html; charset=utf-8&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">//判断用户是否授权</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'用户未授权'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;location:forbidden.php&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">///下面是进行摸个记录操作</span>
<span style="color: #666666; font-style: italic;">//删除条记录，或者修改某条记录……</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;">&nbsp;</pre></td></tr></table></div>

</blockquote>
<p>这类代码，在开发中很常见，我们会发现，一个没有权限用户，操作该记录，网页会跳转到未授权页面，但是：<strong>记录任然被修改了</strong>，问题我们找到了，一般操作人员，对于js跳转会知道是前端浏览器跳转的。但是对于php操作跳转，<span style="color: #9b00d3;"><span style="text-decoration: underline;">错误认为是服务器跳转，好像php以执行到location，然后就终止了下面运行。 </span></span><span style="color: #000000;">其实，知道header函数真实意义就很容易理解了：<b>header()</b> is used to send a raw <acronym>HTTP </acronym>header！</span></p>
<p>header location 302实际上只是如下：</p>
<blockquote>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image35.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border-width: 0px;" title="response 服务器302响应头" alt="response 服务器302响应头" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb35.png" width="576" height="266" border="0" /></a></pre>
<pre>跟其它普通echo 函数没有多大区别，只是给header信息头,echo 一行而已。</pre>
<pre></pre>
</blockquote>
<p><strong>屏蔽Bug方法：</strong></p>
<pre></pre>
<p>知道了，发送header跳转，服务器不会终止程序，因此为了安全起见。<span style="text-decoration: underline;"><span style="color: #9b00d3;">header locaction后，最好加一句exit()函数。</span></span> 这样，php解析引擎就会停止解析了！我们正确方法是封装个header_302方法</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">/*header_302跳转*
 * *
 *@author http://blog.chacuo.net/
 * @param string $url 跳转url
 */</span>
<span style="color: #000000; font-weight: bold;">function</span>  header_302<span style="color: #009900;">&#40;</span><span style="color: #000088;">$url</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #b1b100;">if</span><span style="color: #009900;">&#40;</span><span style="color: #990000;">headers_sent</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#123;</span>
		<span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'header 已经发送过！'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #009900;">&#125;</span>
	<span style="color: #990000;">header</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;location:<span style="color: #006699; font-weight: bold;">$url</span>&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #990000;">exit</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

</blockquote>
<p>后记：这类问题，不光出在php程序中，其它很多header loction跳转语言程序，原理相同。都有类似功能，很多时候。都是使用时候没有注意，造成的。 容易在代码走查中，遗漏掉！好了，先到这里，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/276.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式断言、巡视（Assertions）、正向断言、反向断言</title>
		<link>http://blog.chacuo.net/262.html</link>
		<comments>http://blog.chacuo.net/262.html#comments</comments>
		<pubDate>Fri, 14 Jun 2013 15:50:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=262</guid>
		<description><![CDATA[断言（Assertions）在正则表达式概念里面难理解，它通常指的是在目标字符串的当前匹配位置进行的一种测试但 [...]]]></description>
				<content:encoded><![CDATA[<p>断言（Assertions）在正则表达式概念里面难理解，它通常指的是在目标字符串的当前匹配位置进行的一种测试但这种测试并不占用目标字符串，也即不会移动模式在目标字符串中的当前匹配位置。详细可以看看,<a title="正则表达式匹配过程" href="http://blog.chacuo.net/255.html" rel="正则表达式匹配过程" target="_blank">正则表达式匹配解析过程探讨分析（正则表达式匹配原理）</a>，里面提到“<strong>零宽度</strong>“很多元字符，只是对特殊位置进行匹配，它们可以理解为断言。</p>
<p><strong>断言元字符</strong></p>
<p>常见断言元字符有：&nbsp; \b, \B, \A, \Z, \z, ^ ,$ 它们只是表示特殊位置，各自作用如有字符串AB,带位置表示为：<sub>0</sub>A<sub>1</sub>B<sub>2</sub></p>
<blockquote><table class="table" border="1" rules="all" cellspacing="0" width="935" frame="box">
<thead>
<tr valign="top">
<th width="316">元字符</th>
<th width="617">意义(以上面带位置字符串说明)</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="316"><strong>^</strong></td>
<td valign="top" width="617">行首，字符串首 表示位置0</td>
</tr>
<tr>
<td valign="top" width="316"><strong>$</strong></td>
<td valign="top" width="617">行尾，字符串尾部，表示位置2</td>
</tr>
<tr>
<td valign="top" width="316">\b</td>
<td valign="top" width="617">字分界线，可以表示：0,2位置</td>
</tr>
<tr>
<td valign="top" width="316">\B</td>
<td valign="top" width="617">非字分界线，可以表示1位置</td>
</tr>
<tr>
<td valign="top" width="316">\A</td>
<td valign="top" width="617">目标的开头（独立于多行模式） 表示位置0</td>
</tr>
<tr>
<td valign="top" width="316">\Z</td>
<td valign="top" width="617">目标的结尾或位于结尾的换行符前（独立于多行模式） 表示位置2</td>
</tr>
<tr>
<td valign="top" width="316">\z</td>
<td valign="top" width="617">目标的结尾（独立于多行模式）表示位置2</td>
</tr>
<tr>
<td valign="top" width="316">\G</td>
<td valign="top" width="617">目标中的第一个匹配位置</td>
</tr>
<tr>
<td valign="top" colspan="2">A,Z,z,G很少使用</td>
</tr>
</tbody>
</table>
</blockquote>
<p>这些断言的测试都是一些基于当前位置的测试，断言还支持更多复杂的测试条件。更复杂的断言以子模式方式来表示，它包括先行（前向)断言(Lookahead assertions)和后行（后向）断言(Lookbehind assertions)，这些断言判断只做匹配判断条件，不会记录在匹配结果中，不会匹配字符。</p>
<p><strong>先行断言、正向断言、正向巡视（Lookahead assertions）</strong></p>
<p>先行断言，常有表示（?=pattern)，从当前匹配位置开始测试后面匹配字符串是否成立，还有(?!pattern)这样两种格式，我们来看看一个例子。源字符串：“abc100”，正则表达式是：<br />/[a-z]+(?=\d+)/ ，我们分析下过程如下图：</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image31.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式先行断言、正向断言、正向巡视" border="0" alt="正则表达式先行断言、正向断言、正向巡视" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb31.png" width="842" height="364"></a></pre>
</blockquote>
<p>首先由正则表达式字符 [a-z]+ 取得控制权,匹配字符：”abc”，位置从”0”开始匹配，变成3。从该位置测试/d+是否成立。匹配到字符100，返回成立。因此正则表达式正向断言成功。返回匹配字符串”abc”</p>
<p>(?!pattern) 只是，正向匹配，当后面没有匹配成功，将返回真。以下是系统源字符串：abc100，测试结果如下：</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image32.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式先行断言、正向断言、正向巡视" border="0" alt="正则表达式先行断言、正向断言、正向巡视" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb32.png" width="845" height="330"></a></pre>
<p>&nbsp;</p>
<pre></pre>
</blockquote>
<p><strong>后行断言、反向断言、反向巡视（Lookbehind assertions）</strong></p>
<p>后行断言，常见表达式是：(?&lt;=pattern)或者(?&lt;!pattern)格式。正则表达式里面，不要出现不固定长度量词，可能会出现死循环。匹配出错。表示当前位置左边将出现匹配字符，则返回真，后面匹配正常。因为如果它出现在最左边，默认位置从0开始，匹配都是失败的。一般都从后面正则表达式开始匹配，再回溯，直到匹配到为止。我们看看下面例子：源字符串：“abc100+=“，正则表达式是：”(?&lt;=\w)\w+”，匹配过程如下图：</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image33.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式后行断言、反向断言、反向巡视" border="0" alt="正则表达式后行断言、反向断言、反向巡视" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb33.png" width="850" height="421"></a></pre>
<p>&nbsp;</p>
<pre></pre>
</blockquote>
<p>首先由正则表达式字符 /\w+/取得控制权,匹配字符：”abc100”，位置从”0”开始匹配，匹配到6个字符。从该位置0检测左变\w匹配失败。因此/\w+/从字符b开始匹配到”bc100”，测试它左侧有字符”a”，反向断言正确。因此匹配到字符串“bc100”,(?&lt;!pattern)，只是没有匹配成功返回真，其它都一样！</p>
<p><strong>后记：</strong>从这篇文章，我们发现搜索特点都是从左到有，一般正向断言放到，正则表达式后，反向断言放到匹配正则表达式前。但是，这里也可以放到前或后。这里就不再举例。欢迎交流讨论！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/262.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式匹配解析过程探讨分析（正则表达式匹配原理）</title>
		<link>http://blog.chacuo.net/255.html</link>
		<comments>http://blog.chacuo.net/255.html#comments</comments>
		<pubDate>Fri, 14 Jun 2013 10:03:35 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=255</guid>
		<description><![CDATA[已经有多篇关于正则表达式介绍的文章，随着我们越来越多使用正则表达式，想对性能做优化、减少我们正则表达式书写匹配 [...]]]></description>
				<content:encoded><![CDATA[<p>已经有多篇关于正则表达式介绍的文章，随着我们越来越多使用正则表达式，想对性能做优化、减少我们正则表达式书写匹配Bug。我们不得不进一步深入了解正则表达式执行过程了。下面我们一起学习，分析下正则表达式执行过程。我们会用regexbuddy测试工具分解执行过程，具体工具使用，可以看：<a title="正则表达式regexbuddy工具推荐" href="http://blog.chacuo.net/238.html" rel="正则表达式regexbuddy工具推荐">正则表达式性能测试工具推荐、优化工具推荐(regexbuddy推荐)</a>。要了解正则表达式解析过程前，我们先来熟悉几个概念。</p>
<ul>
<li>
<h3><strong>常见正则表达式引擎</strong></h3>
</li>
</ul>
<p>引擎决定了正则表达式匹配方法及内部搜索过程，了解它至关重要的。目前主要流行引擎有：DFA,NFA两种引擎，我们比较区分下。</p>
<blockquote><table class="table" border="1" rules="all" cellspacing="0" width="935" frame="box">
<thead>
<tr valign="top">
<th width="316">引擎</th>
<th width="617">区别点</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top" width="316"><strong>DFA<br /></strong>Deterministic finite automaton <br />确定型有穷自动机</td>
<td valign="top" width="617">DFA引擎它们不要求回溯（并因此它们永远不测试相同的字符两次），所以匹配<strong>速度快</strong>！DFA引擎还可以匹配最长的可能的字符串。不过DFA引擎只包含有限的状态，所以它不能匹配具有反向引用的模式，还<strong>不可以捕获子表达式</strong>。代表性有：<strong>awk,egrep,flex,lex,MySQL,Procmail</strong></td>
</tr>
<tr>
<td valign="top" width="316"><strong>NFA<br /></strong>Non-deterministic finite automaton　非确定型有穷自动机，又分为传统NFA,Posix NFA</td>
<td valign="top" width="617">传统的NFA引擎运行所谓的“贪婪的”匹配回溯算法（longest-leftmost），以指定顺序测试正则表达式的所有可能的扩展并接受第一个匹配项。传统的NFA回溯可以访问完全相同的状态多次，在最坏情况下，它的执行速度可能<strong>非常慢</strong>，但它<strong>支持子匹配</strong>。代表性有：<strong>GNU Emacs,Java,ergp,less,more,.NET语言,<br />PCRE library,Perl,PHP,Python,Ruby,sed,vi等，</strong>一般高级语言都采用该模式。</td>
</tr>
</tbody>
</table>
<p> 
<p>DFA以字符串字符，逐个在正则表达式匹配查找，而NFA以正则表达式为主，在字符串中逐一查找。尽管速度慢，但是对操作者来说更简单，因此应用更广泛！下面所有以NFA引擎举例说明，解析过程！</p>
<p>&nbsp;</p>
</blockquote>
<ul>
<li>
<h3><strong>解析引擎眼中的字符串组成</strong></h3>
</li>
</ul>
<p>对于字符串“DEF”而言，包括D、E、F三个字符和 0、1、2、3 四个数字位置：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，对于正则表达式而言所有源字符串，都有字符和位置。正则表达式会从0号位置，逐个去匹配的。</p>
<ul>
<li>
<h3><strong>占有字符和零宽度</strong></h3>
</li>
</ul>
<p>正则表达式匹配过程中，如果子表达式匹配到的是字符内容，而非位置，并被保存到最终的匹配结果中，那么就认为这个子表达式是占有字符的；如果子表达式匹配的仅仅是位置，或者匹配的内容并不保存到最终的匹配结果中，那么就认为这个子表达式是零宽度的。占有字符是互斥的，零宽度是非互斥的。也就是一个字符，同一时间只能由一个子表达式匹配，而一个位置，却可以同时由多个零宽度的子表达式匹配。常见零宽字符有：^，(?=)等</p>
<ul>
<li>
<h3><strong>正则表达式匹配过程详解实例</strong></h3>
</li>
</ul>
<p>我们掌握了上面几个概念，我们接下来分析下几个常见的解析过程。结合使用软件regexBuddy来分析。</p>
<p><strong>Demo1: </strong>源字符DEF,对应标记是：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，匹配正则表达式是：/DEF/</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image28.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式解析过程" border="0" alt="正则表达式解析过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb28.png" width="855" height="341"></a></pre>
<p>过程可以理解为：首先由正则表达式字符 /D/ 取得控制权，从位置0开始匹配，由 /D/ 来匹配“D”，匹配成功，控制权交给字符 /E/ ；由于“D”已被 /D/ 匹配，所以 /E/ 从位置1开始尝试匹配，由 /E/ 来匹配“E”，匹配成功，控制权交给 /F/ ；由 /F/ 来匹配“F”，匹配成功。 </p>
</blockquote>
<p><strong>Demo2:</strong>源字符DEF,对应标记是：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，匹配正则表达式是：/D\w+F/</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image29.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式解析过程" border="0" alt="正则表达式解析过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb29.png" width="859" height="445"></a> </pre>
<p>过程可以理解为：首先由正则表达式字符 /D/ 取得控制权，从位置0开始匹配，由 /D/ 来匹配“D”，匹配成功，控制权交给字符 /\w+/ ；由于“D”已被 /D/ 匹配，所以 /\w+/ 从位置1开始尝试匹配，\w+贪婪模式，会记录一个备选状态，默认会匹配最长字符，直接匹配到EF，并且匹配成功，当前位置3了。并且把控制权交给 /F/ ；由 /F/ 匹配失败，\w+匹配会回溯一位，当前位置变成2。并把控制权交个/F/，由/F/匹配字符F成功。因此\w+这里匹配E字符,匹配完成！</p>
</blockquote>
<p><strong>Demo3:</strong>源字符DEF,对应标记是：<sub color="blue">0</sub>D<sub color="blue">1</sub>E<sub color="blue">2</sub>F<sub color="blue">3</sub>，匹配正则表达式是：/^(?=D)[D-F]+$/</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image30.png"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="正则表达式解析过程" border="0" alt="正则表达式解析过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb30.png" width="862" height="469"></a> </pre>
<p>过程可以理解为：元字符 /^/ 和 /$/ 匹配的只是位置，顺序环视 /(?=D)/ （匹配当前位置，右边是否有字符“D”字符出现）只进行匹配，并不占有字符，也不将匹配的内容保存到最终的匹配结果，所以都是<strong>零宽度</strong>的。 首先由元字符 /^/ 取得控制权，从位置0开始匹配， /^/ 匹配的就是开始位置“位置0”，匹配成功，控制权交给顺序环视 /(?=D)/；/(?=D])/ 要求它所在位置右侧必须是字母”D”才能匹配成功，零宽度的子表达式之间是不互斥的，即同一个位置可以同时由多个零宽度子表达式匹配，所以它也是从位置0尝试进行匹配，位置0的右侧是字符“D”，符合要求，匹配成功，控制权交给 /[D-F]+/ ；因为 /(?=D)/ 只进行匹配，并不将匹配到的内容保存到最后结果，并且 /(?=D)/ 匹配成功的位置是位置0，所以 /[D-F]+/ 也是从位置0开始尝试匹配的， /[D-F]+/ 首先尝试匹配“D”，匹配成功，继续尝试匹配，直到匹配完”EF”，这时已经匹配到位置3，位置3的右侧已没有字符，这时会把控制权交给 /$/，元字符 /$/ 从位置3开始尝试匹配，它匹配的是结束位置，也就是“位置3”，匹配成功。此时正则表达式匹配完成，报告匹配成功。匹配结果为“DEF”，开始位置为0，结束位置为3。其中 /^/ 匹配位置0， /(?=D)/ 匹配位置0， /[D-F]+/ 匹配字符串“DEF”， /$/ 匹配位置3。</p>
<p>&nbsp;</p>
</blockquote>
<p><strong>后记：</strong>上面这几个例子，我们分析了正则表达式普通匹配，还有回溯过程，然后零宽度字符，匹配过程。当然，给出的例子比较简单，实际过程中会遇到更长，更复杂的正则表达式。但是，思想是类似的。只要我们把我解析原理，都可以逐一分解的。好了，就到这里，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/255.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式性能测试工具推荐、优化工具推荐(regexbuddy推荐)</title>
		<link>http://blog.chacuo.net/238.html</link>
		<comments>http://blog.chacuo.net/238.html#comments</comments>
		<pubDate>Thu, 13 Jun 2013 14:59:17 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web性能]]></category>
		<category><![CDATA[学习工具]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=238</guid>
		<description><![CDATA[前不久，我们推荐了个正则表达式入门学习工具。正则表达式工具推荐（学习工具、测试工具） ，今天我们看下，正则表达 [...]]]></description>
				<content:encoded><![CDATA[<p>前不久，我们推荐了个正则表达式入门学习工具。<a href="http://blog.chacuo.net/198.html">正则表达式工具推荐（学习工具、测试工具）</a> ，今天我们看下，正则表达式的性能测试工具。这里我们先说下，为什么需要这样的工具，这个工具有什么作用呢？</p>
<ul>
<li>
<h3><span style="font-weight: bold">为什么需要性能测试工具</span></h3>
</li>
</ul>
<h3></h3>
<p>我们都知道，正则表达式使用进行搜索查找，没有字符串直接查找快！而且性能是几何倍数下降。那么，为什么正则表达式速度会比字符串搜索慢呢。我们来看看，正则表达式查找字符串的匹配过程吧。正则表达式由一些元字符，普通字符，量词字符组合成。默认情况下，这些量词元字符（*,+,?)都是贪婪模式，会最大长度匹配字符串。我们知道，正则表达式往往搜索路径会有多个，我们看看，下面匹配过程。就知道，主要影响正则表达式执行性能有哪些了。</p>
<p>正则表达式匹配过程如：\d+abc，元字符是：”12345bdc”，查找会从左向右进行，\d+，贪婪模式，一下子匹配到12345，然后bdc与\d+不能匹配，”abc”中,”a”字符，开始匹配”bdc”，发现匹配失败。正则表达式开始回溯匹配（贪婪模式量词开始逐一减少匹配字符长度)，\d+只匹配”1234”，”5bdc”与”abc”匹配，任然失败。\d+继续减少匹配长度为：”123”，”45bdc”与”abc”匹配，任然失败。继续回退，直到\d+匹配”1”，用”2345bdc”与”bdc”匹配，任然失败。整个匹配就失败了。</p>
<p>从上面过程中，我们发现，每次回溯，要重新操作匹配因此匹配搜索次数，直接影响正则表达式的性能。做正则表达式性能优化，一般就是优化查询的次数。这个是我们分析过程，如果有个工具能够实实在在看到每一步匹配过程，对于我们优化正则表达式将带来太多方便了。这里介绍工具是：<strong>regexbuddy软件</strong>，它就是一个实实在在看到匹配过程工具。</p>
<ul>
<li>
<h3><span style="font-weight: bold">regexbuddy工具怎么样使用，使用介绍</span></h3>
</li>
</ul>
<blockquote><pre>1、安装完<strong>regexbuddy</strong></pre>
<p></p>
<pre><strong></strong></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image23.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy介绍" border="0" alt="regexbuddy介绍" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb23.png" width="863" height="523"></a></pre>
<p>该工具支持多种程序语言正则表达式，如：perl,pcre,javascript,python,ruby,c#,java等等，还能自动生成程序代码，并且内部带有大量的常用正则表达式。</p>
<pre>2、一般切换到side by side：</pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image24.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy使用" border="0" alt="regexbuddy使用" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb24.png" width="865" height="549"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre>3、匹配过程</pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image25.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy匹配过程" border="0" alt="regexbuddy匹配过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb25.png" width="867" height="524"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image26.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy匹配过程" border="0" alt="regexbuddy匹配过程" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb26.png" width="866" height="524"></a></pre>
<p>从上面一个匹配看，这个简单一个匹配，搜索了8次，进行了不断查找。如果我们已经准确知道自己要匹配什么样字符，我们可以对源正则表达式修改下，减少匹配次数。就达到优化正则表达式目的，提高匹配效率！</p>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image27.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="regexbuddy优化正则表达式" border="0" alt="regexbuddy优化正则表达式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb27.png" width="869" height="526"></a></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
<p></p>
<pre></pre>
</blockquote>
<p><strong>后记：</strong>这个工具是不是很强大呢，你知道在baidu搜索，该关键字：<strong>regexbuddy，</strong>就可以方便下载到。通过该工具，对我们写出好的高性能正则表达式确实能带来很大帮助。有时候可能一个小小修改，自己程序正则表达式匹配速度可能几个数量级的提升。好了，欢迎大家交流，你有好的工具、方法，欢迎留言，可以给更多朋友分享！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/238.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式单行、多行模式简介（使用说明）</title>
		<link>http://blog.chacuo.net/225.html</link>
		<comments>http://blog.chacuo.net/225.html#comments</comments>
		<pubDate>Wed, 12 Jun 2013 14:13:00 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=225</guid>
		<description><![CDATA[继上几篇正则表达式相关说明（详情：正则表达式 )，我们今天继续讨论下，它的单行，多行模式使用，及容易出现错误地 [...]]]></description>
				<content:encoded><![CDATA[<p>继上几篇正则表达式相关说明（详情：<a title="正则表达式学习" href="http://blog.chacuo.net/tag/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F" target="_blank">正则表达式</a> )，我们今天继续讨论下，它的单行，多行模式使用，及容易出现错误地方。单行，多行模式，都是正则表达式的模式修饰符里面出现的参数。目前常用正则表达式都有该使用选项，如：javascript 正则表达式，一般是：”/正则表达式匹配字符/修饰符“ ，最后一个”/” 后面是修饰符。然后，php也是类似的，c#，python等，一般调用正则表达式的匹配函数，都有一个另外选项的，设置模式。</p>
<ul>
<li>
<h3><font style="font-weight: bold">单行、多行模式容易出现理解错误</font></h3>
</li>
</ul>
<h3><strong></strong></h3>
<p>为什么说，容易出现理解错误呢，它们英文对应说明是：SingleLine ，MultiLine，刚好是单行、多行意思。因此，很多朋友就会从字面理解里面，得出以下结论：（哈哈、刚刚使用，我也是这些朋友中一员）</p>
<p><font color="#ff0000">1、单行，就是从头到尾匹配，多行就是如果匹配字符串，里面有换行符，就匹配到之前</font></p>
<p><font color="#ff0000">2、单行跟多行是冲突的，一次只能指定一个选项，不能同时使用</font></p>
<p>这样来理解其实，很容易就会这样的。我们来看看，官方手册里面怎么说的。</p>
<ul>
<li>
<h3><font style="font-weight: bold">单行、多行模式官方解释</font></h3>
</li>
</ul>
<blockquote><table class="table" border="1" rules="all" cellspacing="0" frame="box">
<thead>
<tr valign="top">
<th width="16%">模式符</th>
<th width="84%">描述</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="top">s(单行)</td>
<td valign="top">如果设置了这个修饰符, 模式中的<strong>点号元字符</strong><u>匹配所有字符</u>, 包含换行符. 如果没有这个 修饰符, 点号不匹配换行符</td>
</tr>
<tr>
<td valign="top">m(多行)</td>
<td valign="top">目标字符串是由单行字符组成的(然而实际上它可能会包含多行), &#8220;行首&#8221;元字符(^)仅匹配字符串的开始位置, 而&#8221;行末&#8221;元字符($)仅匹配字符串末尾。当这个修饰符设置之后, &#8220;行首&#8221;和&#8221;行末&#8221;就会匹配目标字符串中任意换行符（\n)之前或之后</td>
</tr>
</tbody>
</table>
<p>&nbsp;</p>
</blockquote>
<p>通过上面说明，其实这2个修饰符都只是，修改正则表达式常见元字符的匹配范围了。如果加”s”修饰符,元字符”.” 将能够匹配换行符(\n)，如果加”m”修饰符，元字符”$”，将只匹配到”\n”字符前；元字符”^”，将匹配到”\n”字符后。我们还是举例说明吧！（下面关于正则表达式?字符，可以看看前面一节:<a title="正则表达式(regex) 贪婪模式、懒惰模式使用" href="http://blog.chacuo.net/211.html" rel="正则表达式(regex) 贪婪模式、懒惰模式使用">正则表达式(regex) 贪婪模式、懒惰模式使用</a>)</p>
<ul>
<li>
<h3><font style="font-weight: bold">举例，看单行应用</font></h3>
</li>
</ul>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">///读取hao123.com首页</span>
<span style="color: #666666; font-style: italic;">///并且去掉里面script代码</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 *去掉script标签*
 * @author chengmo
 * @copyright http://blog.chacuo.net/
 * @param string $content 原字符串 
 * @param int $style 匹配模式
 * @return string
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> remove_script<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #339933;">,</span><span style="color: #000088;">$style</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$reg</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$style</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span>?<span style="color: #0000ff;">&quot;%&lt;script.*?&gt;.*?&lt;/script&gt;%&quot;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;%&lt;script.*?&gt;.*?&lt;/script&gt;<span style="color: #009933; font-weight: bold;">%s</span>&quot;</span><span style="color: #339933;">;</span>
&nbsp;
	<span style="color: #b1b100;">return</span> <span style="color: #990000;">preg_replace</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reg</span><span style="color: #339933;">,</span><span style="color: #0000ff;">&quot;&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.hao123.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #b1b100;">echo</span> remove_script<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>


<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #339933;">&amp;</span>nbsp<span style="color: #339933;">;</span></pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image18.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式单行匹配模式" border="0" alt="正则表达式单行匹配模式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb18.png" width="925" height="269"></a></pre>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image19.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式单行匹配模式" border="0" alt="正则表达式单行匹配模式" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb19.png" width="928" height="308"></a></pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
</blockquote>
<ul>
<li>
<h3><font style="font-weight: bold">举例，看多行应用</font></h3>
</li>
</ul>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #666666; font-style: italic;">///读取hao123.com首页</span>
<span style="color: #666666; font-style: italic;">///读取meta标签内容</span>
&nbsp;
<span style="color: #009933; font-style: italic;">/**
 *读取meta标签内容*
 * @author chengmo
 * @copyright http://blog.chacuo.net/
 * @param string $content 原字符串 
 * @param int $style 匹配模式
 * @return string
 */</span>
<span style="color: #000000; font-weight: bold;">function</span> read_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #339933;">,</span><span style="color: #000088;">$style</span><span style="color: #339933;">=</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
	<span style="color: #000088;">$reg</span> <span style="color: #339933;">=</span> <span style="color: #000088;">$style</span> <span style="color: #339933;">==</span> <span style="color: #cc66cc;">1</span>?<span style="color: #0000ff;">&quot;%^&lt;meta.*?/&gt;%&quot;</span><span style="color: #339933;">:</span><span style="color: #0000ff;">&quot;%^&lt;meta.*?&gt;\s+$%m&quot;</span><span style="color: #339933;">;</span>	
	<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$reg</span><span style="color: #339933;">,</span><span style="color: #000088;">$content</span><span style="color: #339933;">,</span><span style="color: #000088;">$arr</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
	<span style="color: #b1b100;">return</span> <span style="color: #000088;">$arr</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #000088;">$content</span> <span style="color: #339933;">=</span> <span style="color: #990000;">file_get_contents</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">'http://www.hao123.com'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span>read_meta<span style="color: #009900;">&#40;</span><span style="color: #000088;">$content</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image20.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式多行" border="0" alt="正则表达式多行" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb20.png" width="863" height="469"></a></pre>
<pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image21.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb21.png" width="868" height="386"></a></pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
<pre>&nbsp;</pre>
</blockquote>
<p><strong>后记：</strong><u><font color="#9b00d3">s，m 修饰符只对，几个特殊元字符有改变。如果你正则表达式中没有那几个元字符。开启s,m字符前后将没有什么变化的。</font></u>对于上面读取hao123.com代码，我们可以继续同时使用s,m模式。如：”%&lt;script.*?&gt;.*?(^currentProfile.*$).*?&lt;/script&gt;%sm” ，匹配所有script标签，并且里面js代码，有一行以curentProfile开头字符串。（以下是正则表达式，单行多行一起使用）</p>
<blockquote><pre><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image22.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="正则表达式单行多行" border="0" alt="正则表达式单行多行" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb22.png" width="855" height="384"></a></pre>
</blockquote>
<p></script></p>
<pre></pre>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/225.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式(regex) 贪婪模式、懒惰模式使用</title>
		<link>http://blog.chacuo.net/211.html</link>
		<comments>http://blog.chacuo.net/211.html#comments</comments>
		<pubDate>Tue, 11 Jun 2013 14:26:02 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[学习心得]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=211</guid>
		<description><![CDATA[正则表达式贪婪匹配模式，对于初学者，往往也很容易出错。有时候需要匹配一个段代码内容，发现匹配与想要不一致。发现 [...]]]></description>
				<content:encoded><![CDATA[<p>正则表达式贪婪匹配模式，对于初学者，往往也很容易出错。有时候需要匹配一个段代码内容，发现匹配与想要不一致。发现原来，跟贪婪模式有关系。如下，我们看下例子：</p>
<ul>
<li>
<h3><font style="font-weight: bold">什么是贪婪模式</font></h3>
</li>
</ul>
<blockquote><p>字符串有: “&lt;h3&gt;abd&lt;/h3&gt;&lt;h3&gt;bcd&lt;/h3&gt;”，我们想匹配&lt;h3&gt;…&lt;/h3&gt;内容，正则表达式如下：</p>
<p>1、h3开头与结尾，”&lt;h3&gt;待添加&lt;/h3&gt;”&nbsp;&nbsp; &lt;h3&gt;&lt;/h3&gt;都作为普通字符</p>
<p>2、中间可以出现任意字符，个数可以是0个或者多个，正则表达式可以用：.* ，“.”代表任意字符，默认模式不匹配换行,”*” 重复前面字符0个或者多个。</p>
<p>3、最终我们考虑结果将是：”&lt;h3&gt;.*&lt;/h3&gt;” ，也可以是：”&lt;h3&gt;.{0,}&lt;/h3&gt;”&nbsp; ｛｝代表，重复前面指定个数字符，以下用到是，正则表达式调试工具截图，软件可以看：<a href="http://blog.chacuo.net/198.html">正则表达式工具推荐（学习工具、测试工具）</a></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image14.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb14.png" width="821" height="450"></a></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image15.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb15.png" width="817" height="384"></a></p>
<p>2种结果都一样，这是我们不希望得到的，我们希望从左边开始，第一个出现&lt;/h3&gt;，就开始匹配。以上这种模式，是贪婪模式，也是正则表达式默认以这个方法匹配。表示重复字符，操作符，默认都是贪婪模式，如：.*,.+,.{1,},.{0,} 都会匹配最大长度字符。<u><font color="#0000ff">正则表达式元字符，量词默认首先最大匹配字符串，这些量词有：+,*,?,{m,n} 。一开始匹配，就直接匹配到最长字符串。</font></u></p>
</blockquote>
<ul>
<li>
<h3><font style="font-weight: bold">什么是懒惰模式</font></h3>
</li>
</ul>
<h3><strong></strong></h3>
<p>既然上面几种，表示字符重复个数，元字符默认都是贪婪模式。如果，我们需要最小长度匹配，也就是懒惰模式，怎么样写正则表达式呢？其实，正则表达式里面通用方法是，在表示重复字符元字符，后面加多一个”?”字符即可。上面正则表达式可以写成：”&lt;h3&gt;.*?&lt;/h3&gt;”，或者”&lt;h3&gt;.{0,}?&lt;/h3&gt;” 都可以。</p>
<blockquote><p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image16.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb16.png" width="820" height="405"></a></p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image17.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb17.png" width="825" height="490"></a></p>
<p>懒惰模式，就匹配到我们需要字符串了。</p>
</blockquote>
<p><strong>总结：</strong>正则表达式，表示字符串重复个数元字符，’?,+,*,{}’ 默认都会选择贪婪模式，会最大长度匹配字符串，而要切换到懒惰模式，就只是在该元字符，后面加多一个”?” 即可切换到非贪婪模式（懒惰模式）。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/211.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式工具推荐（学习工具、测试工具）</title>
		<link>http://blog.chacuo.net/198.html</link>
		<comments>http://blog.chacuo.net/198.html#comments</comments>
		<pubDate>Mon, 10 Jun 2013 15:25:41 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[学习工具]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=198</guid>
		<description><![CDATA[我们学习正则表达式，有个好的工具，对于我们初学者还是不错的选择。这里推荐大家使用：RegExBuilder工具 [...]]]></description>
				<content:encoded><![CDATA[<p>我们学习正则表达式，有个好的工具，对于我们初学者还是不错的选择。这里推荐大家使用：RegExBuilder工具，该工具支持正则表达式多种扩展类型匹配方式，包括：单行，多行，从右向左，忽略大小写等。匹配结果直观显示。截图如下：</p>
<p>&nbsp;</p>
<blockquote><p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image13.png"><img style="background-image: none; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; padding-top: 0px; border: 0px;" title="image" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb13.png" width="830" height="490" border="0" /></a></p></blockquote>
<p>将原始字符串输入，就可以在正则表达式窗口写入表达式，一边写一边有提示字符。如果有出错，还有错误提示。下面就会显示匹配到的结果。非常方便！该工具，可以搜索：<a title="搜索：RegExbuider" href="http://www.baidu.com/s?ie=utf-8&amp;bs=regexbuilder&amp;f=8&amp;rsv_bp=1&amp;rsv_spt=3&amp;wd=regexbuilder&amp;inputT=0" target="_blank">regExbuilder</a> ，有好的工具，欢迎交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/198.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式（regex)入门、元字符(特殊字符)、学习提高、学习实例</title>
		<link>http://blog.chacuo.net/190.html</link>
		<comments>http://blog.chacuo.net/190.html#comments</comments>
		<pubDate>Mon, 10 Jun 2013 10:22:48 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=190</guid>
		<description><![CDATA[什么是正则表达式呢？ 正则表达式，又称正规表示法、常规表示法（英语：Regular Expression，在代 [...]]]></description>
				<content:encoded><![CDATA[<ul>
<li>
<h3><font style="font-weight: bold">什么是正则表达式呢？</font></h3>
</li>
</ul>
<p>正则表达式，又称正规表示法、常规表示法（英语：Regular Expression，在代码中常简写为regex、regexp或RE），它是计算机科学的一个概念。正则表达式使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。几乎在各种计算机编程语言中都有用到。可以分为普通正则表达式、扩展正则表达式、高级正则表达式。普通正则表达式在linux shell中常用到，高级正则表达式语法规范，基本由perl演化而来。目前常见程序语言（php,perl,python,java,c#)都支持高级正则表达式。</p>
<ul>
<li>
<h3><font style="font-weight: bold">我们为什么要学习正则表达式？</font></h3>
</li>
</ul>
<p>高级程序语言的正则表达式几乎都从perl语言发展而来，因此，语法几乎一致。你学好了，一门正则表达式语言。几乎在所有程序语言中就可以用到。就像，我知道sql语法，后端mysql,mssql几乎都通用。这个也是我们需要学好正则表达式一个原因，通用性。另外一个原因是：正则表达式强大的文本匹配功能。很多文本匹配处理，如果没有正则表达式，还真的很难做出来。如：从一段字符串，读出手机号格式，我们如果用字符串查找，需要做循环，需要写判断。估计耗费不少代码，开发时间。如果用正则表达式，就一行代码就可以了。匹配所有成对的：html标签，如果要做这个，我们发现非常复杂，要处理层次，要匹配标签。一般同人短短几个小时可能完成不了。如果用正则表达式，估计也就几分钟而已。</p>
<ul>
<li>
<h3><font style="font-weight: bold">正则表达式字符串格式</font></h3>
</li>
</ul>
<p>既然我们知道正则表达式重要性，通用性。那么我们对常见格式可以了解下。一般正则表达式由：普通字符+特殊字符（元字符）一起组成的字符串。如：匹配“ab开头，后面紧跟数字字符串“&#160;&#160; “ab\d+”&#160; 这其中ab就是普通字符，\d代表可以是0-9数字，+代表前面字符可以出现1次或以上。哈哈，看起来还真的很容易吧！</p>
<p>正则表达式无论是普通还是扩展还是高级正则表达式。不同之处，可能在特殊字符方面有些不同。很多特殊字符，可以组合，形成一套新匹配规则。这里就不说太深了。我们一般只要知道它的常见元字符。基本上常见正则表达式就可以写出来了。 </p>
<p>以下是javascript 正则表达式常见的<strong>元字符</strong>：</p>
<blockquote><div>
<table class="table" border="1" rules="all" cellspacing="0" frame="box">
<thead>
<tr valign="top">
<th width="16%">字符</th>
<th width="84%">描述</th>
</tr>
</thead>
<tbody>
<tr valign="top">
<td width="16%">\</td>
<td width="84%">将下一个字符标记为一个特殊字符、或一个原义字符、或一个 后向引用、或一个八进制转义符。例如，&#8217;n&#8217; 匹配字符 &quot;n&quot;。&#8217;\n&#8217; 匹配一个换行符。序列 &#8216;\\&#8217; 匹配 &quot;\&quot; 而 &quot;\(&quot; 则匹配 &quot;(&quot;。</td>
</tr>
<tr valign="top">
<td width="16%">^</td>
<td width="84%">匹配输入字符串的开始位置。如果设置了 <b>RegExp</b> 对象的 <b>Multiline</b> 属性，^ 也匹配 &#8216;\n&#8217; 或 &#8216;\r&#8217; 之后的位置。</td>
</tr>
<tr valign="top">
<td width="16%">$</td>
<td width="84%">匹配输入字符串的结束位置。如果设置了<b>RegExp</b> 对象的 <b>Multiline</b> 属性，$ 也匹配 &#8216;\n&#8217; 或 &#8216;\r&#8217; 之前的位置。</td>
</tr>
<tr valign="top">
<td width="16%">*</td>
<td width="84%">匹配前面的子表达式零次或多次。例如，zo* 能匹配 &quot;z&quot; 以及 &quot;zoo&quot;。 * 等价于{0,}。</td>
</tr>
<tr valign="top">
<td width="16%">+</td>
<td width="84%">匹配前面的子表达式一次或多次。例如，&#8217;zo+&#8217; 能匹配 &quot;zo&quot; 以及 &quot;zoo&quot;，但不能匹配 &quot;z&quot;。+ 等价于 {1,}。</td>
</tr>
<tr valign="top">
<td width="16%">?</td>
<td width="84%">匹配前面的子表达式零次或一次。例如，&quot;do(es)?&quot; 可以匹配 &quot;do&quot; 或 &quot;does&quot; 中的&quot;do&quot; 。? 等价于 {0,1}。</td>
</tr>
<tr valign="top">
<td width="16%">{<i>n</i>}</td>
<td width="84%"><i>n</i> 是一个非负整数。匹配确定的 <i>n</i> 次。例如，&#8217;o{2}&#8217; 不能匹配 &quot;Bob&quot; 中的 &#8216;o&#8217;，但是能匹配 &quot;food&quot; 中的两个 o。</td>
</tr>
<tr valign="top">
<td width="16%">{<i>n</i>,}</td>
<td width="84%"><i>n</i> 是一个非负整数。至少匹配<i>n</i> 次。例如，&#8217;o{2,}&#8217; 不能匹配 &quot;Bob&quot; 中的 &#8216;o&#8217;，但能匹配 &quot;foooood&quot; 中的所有 o。&#8217;o{1,}&#8217; 等价于 &#8216;o+&#8217;。&#8217;o{0,}&#8217; 则等价于 &#8216;o*&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">{<i>n</i>,<i>m</i>}</td>
<td width="84%"><i>m</i> 和 <i>n</i> 均为非负整数，其中<i>n</i> &lt;= <i>m</i>。最少匹配 <i>n</i> 次且最多匹配 <i>m</i> 次。刘， &quot;o{1,3}&quot; 将匹配 &quot;fooooood&quot; 中的前三个 o。&#8217;o{0,1}&#8217; 等价于 &#8216;o?&#8217;。请注意在逗号和两个数之间不能有空格。</td>
</tr>
<tr valign="top">
<td width="16%">?</td>
<td width="84%">当该字符紧跟在任何一个其他限制符 (*, +, ?, {<i>n</i>}, {<i>n</i>,}, {<i>n</i>,<i>m</i>}) 后面时，匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串，而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如，对于字符串 &quot;oooo&quot;，&#8217;o+?&#8217; 将匹配单个 &quot;o&quot;，而 &#8216;o+&#8217; 将匹配所有 &#8216;o&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">.</td>
<td width="84%">匹配除 &quot;\n&quot; 之外的任何单个字符。要匹配包括 &#8216;\n&#8217; 在内的任何字符，请使用象 &#8216;[.\n]&#8216; 的模式。</td>
</tr>
<tr valign="top">
<td width="16%">(<i>pattern</i>)</td>
<td width="84%">匹配<i>pattern</i> 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到，在VBScript 中使用 <b>SubMatches</b> 集合，在JScript 中则使用 <b>$0</b>…<b>$9</b> 属性。要匹配圆括号字符，请使用 &#8216;\(&#8216; 或 &#8216;\)&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">(?:<i>pattern</i>)</td>
<td width="84%">匹配 <i>pattern</i> 但不获取匹配结果，也就是说这是一个非获取匹配，不进行存储供以后使用。这在使用 &quot;或&quot; 字符 (|) 来组合一个模式的各个部分是很有用。例如， &#8216;industr(?:y|ies) 就是一个比 &#8216;industry|industries&#8217; 更简略的表达式。</td>
</tr>
<tr valign="top">
<td width="16%">(?=<i>pattern</i>)</td>
<td width="84%">正向预查，在任何匹配 <i>pattern</i> 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如， &#8216;Windows (?=95|98|NT|2000)&#8217; 能匹配 &quot;Windows 2000&quot; 中的 &quot;Windows&quot; ，但不能匹配 &quot;Windows 3.1&quot; 中的 &quot;Windows&quot;。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始。</td>
</tr>
<tr valign="top">
<td width="16%">(?!<i>pattern</i>)</td>
<td width="84%">负向预查，在任何不匹配Negative lookahead matches the search string at any point where a string not matching <i>pattern</i> 的字符串开始处匹配查找字符串。这是一个非获取匹配，也就是说，该匹配不需要获取供以后使用。例如&#8217;Windows (?!95|98|NT|2000)&#8217; 能匹配 &quot;Windows 3.1&quot; 中的 &quot;Windows&quot;，但不能匹配 &quot;Windows 2000&quot; 中的 &quot;Windows&quot;。预查不消耗字符，也就是说，在一个匹配发生后，在最后一次匹配之后立即开始下一次匹配的搜索，而不是从包含预查的字符之后开始 </td>
</tr>
<tr valign="top">
<td width="16%"><i>x</i>|<i>y</i></td>
<td width="84%">匹配 <i>x</i> 或 <i>y</i>。例如，&#8217;z|food&#8217; 能匹配 &quot;z&quot; 或 &quot;food&quot;。&#8217;(z|f)ood&#8217; 则匹配 &quot;zood&quot; 或 &quot;food&quot;。 </td>
</tr>
<tr valign="top">
<td width="16%">[<i>xyz</i>]</td>
<td width="84%">字符集合。匹配所包含的任意一个字符。例如， &#8216;[abc]&#8216; 可以匹配 &quot;plain&quot; 中的 &#8216;a&#8217;。 </td>
</tr>
<tr valign="top">
<td width="16%">[^<i>xyz</i>]</td>
<td width="84%">负值字符集合。匹配未包含的任意字符。例如， &#8216;[^abc]&#8216; 可以匹配 &quot;plain&quot; 中的&#8217;p'。 </td>
</tr>
<tr valign="top">
<td width="16%">[<i>a-z</i>]</td>
<td width="84%">字符范围。匹配指定范围内的任意字符。例如，&#8217;[a-z]&#8216; 可以匹配 &#8216;a&#8217; 到 &#8216;z&#8217; 范围内的任意小写字母字符。 </td>
</tr>
<tr valign="top">
<td width="16%">[^<i>a-z</i>]</td>
<td width="84%">负值字符范围。匹配任何不在指定范围内的任意字符。例如，&#8217;[^a-z]&#8216; 可以匹配任何不在 &#8216;a&#8217; 到 &#8216;z&#8217; 范围内的任意字符。 </td>
</tr>
<tr valign="top">
<td width="16%">\b</td>
<td width="84%">匹配一个单词边界，也就是指单词和空格间的位置。例如， &#8216;er\b&#8217; 可以匹配&quot;never&quot; 中的 &#8216;er&#8217;，但不能匹配 &quot;verb&quot; 中的 &#8216;er&#8217;。 </td>
</tr>
<tr valign="top">
<td width="16%">\B</td>
<td width="84%">匹配非单词边界。&#8217;er\B&#8217; 能匹配 &quot;verb&quot; 中的 &#8216;er&#8217;，但不能匹配 &quot;never&quot; 中的 &#8216;er&#8217;。</td>
</tr>
<tr valign="top">
<td width="16%">\c<i>x</i></td>
<td width="84%">匹配由<i>x</i>指明的控制字符。例如， \cM 匹配一个 Control-M 或回车符。 <i>x</i> 的值必须为 A-Z 或 a-z 之一。否则，将 c 视为一个原义的 &#8216;c&#8217; 字符。 </td>
</tr>
<tr valign="top">
<td width="16%">\d</td>
<td width="84%">匹配一个数字字符。等价于 [0-9]。 </td>
</tr>
<tr valign="top">
<td width="16%">\D</td>
<td width="84%">匹配一个非数字字符。等价于 [^0-9]。 </td>
</tr>
<tr valign="top">
<td width="16%">\f</td>
<td width="84%">匹配一个换页符。等价于 \x0c 和 \cL。</td>
</tr>
<tr valign="top">
<td width="16%">\n</td>
<td width="84%">匹配一个换行符。等价于 \x0a 和 \cJ。</td>
</tr>
<tr valign="top">
<td width="16%">\r</td>
<td width="84%">匹配一个回车符。等价于 \x0d 和 \cM。</td>
</tr>
<tr valign="top">
<td width="16%">\s</td>
<td width="84%">匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td>
</tr>
<tr valign="top">
<td width="16%">\S</td>
<td width="84%">匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td>
</tr>
<tr valign="top">
<td width="16%">\t</td>
<td width="84%">匹配一个制表符。等价于 \x09 和 \cI。</td>
</tr>
<tr valign="top">
<td width="16%">\v</td>
<td width="84%">匹配一个垂直制表符。等价于 \x0b 和 \cK。</td>
</tr>
<tr valign="top">
<td width="16%">\w</td>
<td width="84%">匹配包括下划线的任何单词字符。等价于&#8217;[A-Za-z0-9_]&#8216;。 </td>
</tr>
<tr valign="top">
<td width="16%">\W</td>
<td width="84%">匹配任何非单词字符。等价于 &#8216;[^A-Za-z0-9_]&#8216;。 </td>
</tr>
<tr valign="top">
<td width="16%">\x<i>n</i></td>
<td width="84%">匹配 <i>n</i>，其中 <i>n</i> 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如， &#8216;\x41&#8242; 匹配 &quot;A&quot;。&#8217;\x041&#8242; 则等价于 &#8216;\x04&#8242; &amp; &quot;1&quot;。正则表达式中可以使用 ASCII 编码。.</td>
</tr>
<tr valign="top">
<td width="16%">\<i>num</i></td>
<td width="84%">匹配 <i>num</i>，其中 <i>num</i> 是一个正整数。对所获取的匹配的引用。例如，&#8217;(.)\1&#8242; 匹配两个连续的相同字符。 </td>
</tr>
<tr valign="top">
<td width="16%">\<i>n</i></td>
<td width="84%">标识一个八进制转义值或一个后向引用。如果 \<i>n</i> 之前至少 <i>n</i> 个获取的子表达式，则 <i>n</i> 为后向引用。否则，如果 <i>n</i> 为八进制数字 (0-7)，则 <i>n</i> 为一个八进制转义值。</td>
</tr>
<tr valign="top">
<td width="16%">\<i>nm</i></td>
<td width="84%">标识一个八进制转义值或一个后向引用。如果 \<i>nm</i> 之前至少有is preceded by at least <i>nm</i> 个获取得子表达式，则 <i>nm</i> 为后向引用。如果 \<i>nm</i> 之前至少有 <i>n</i> 个获取，则 <i>n</i> 为一个后跟文字 <i>m </i>的后向引用。如果前面的条件都不满足，若 <i>n</i> 和 <i>m</i> 均为八进制数字 (0-7)，则 \<i>nm</i> 将匹配八进制转义值 <i>nm</i>。</td>
</tr>
<tr valign="top">
<td width="16%">\<i>nml</i></td>
<td width="84%">如果 <i>n</i> 为八进制数字 (0-3)，且 <i>m</i> 和 <i>l</i> 均为八进制数字 (0-7)，则匹配八进制转义值 <i>nml。</i></td>
</tr>
<tr valign="top">
<td width="16%">\u<i>n</i></td>
<td width="84%">匹配 <i>n</i>，其中 <i>n</i> 是一个用四个十六进制数字表示的 Unicode 字符。例如， \u00A9 匹配版权符号 (?)。</td>
</tr>
</tbody>
</table></div>
</blockquote>
<p>&#160;</p>
<p>从上面元字符里面，我们看到，很多元字符，实际上可以代表一组普通字符。因此，我们要匹配一些字符串，正则表达式往往会有很多种。如：匹配0-9数字，可以用[0-9],\d,[0123456789] ，这样3种都可以，条条大路通罗马，都是对的。那么那一种正则表达式更好呢，性能更高呢，匹配速度更快呢？通过10万次 循环匹配，发现几种几乎相差不大，\d速度比[0-9快，[0-9]比[0123456789]快。从正则表达式精简]程度方面，\d最简单。使用时候，我们尽量用代表字符集元字符去匹配。精简且速度快！</p>
<ul>
<li>
<h3><font style="font-weight: bold">怎么样书写正则表达式呢？</font></h3>
</li>
</ul>
<h3><strong></strong></h3>
<p>我们写正则表达式，都是从分析匹配字符串特点开始，然后逐步补充其它元字符，普通字符。匹配从左到右。</p>
<p><strong>例如：我们要匹配一个手机号码。</strong></p>
<p>1. 分析字符串特点，手机号码是数字，并且是以1开头，11位长</p>
<p>2.可以写”1\d”&#160;&#160; 1开头，后面跟着数字 也可以是：1[0-9]</p>
<p>3.数字长度是11位 ，继续补充1\d{10} ，后面数字长11字符，也可以是：1[0-9]{10} ；{}里面数字，表示它左边字符可以重复出现次数</p>
<p>4.所有字符必须是11位，因此头尾直接必须满足条件，因此可以是：^1\d{10}$ 了。</p>
<p><strong>例如：我们匹配QQ号码</strong></p>
<p>1.分析QQ号码特点是，号码是 最少是5位数，首位字符非0，最大长度，目前到11位了</p>
<p>2.可以先定义首位字符，[1-9]\d&#160;&#160;&#160; 首位字符是1到9，后面是字符</p>
<p>3.后面字符个数在4到10位 [1-9]\d{4,10}</p>
<p>4.所有字符串必须都满足上面匹配，因为可以写成：^[1-9]\d{4,10}</p>
<p><strong>例如：匹配IP地址</strong></p>
<p>1.分析ip结构是，每节 0-255，中间用”.”分割，一共有4节</p>
<p>2.首先我们写第一个0-255 ，可以分解为0-9 一位数,10-99两位数,100-199三位数,200-249三位数第2节,250-255第四节</p>
<p>[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]&#160;&#160; “|”表示或者，计算优先级最低，左右两边可以是多个元字符普通字符组合字符串为一个整体。</p>
<p>3.这样的字符，有三次重复，中间加”.” ，所以结果是：</p>
<p>[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]\. ，因为是点字符是元字符，所有需要转义。这样是不是可以了呢，我们发现有问题，”|”优先级最低，这样会把最后\.字符表，组合为：“25[0-5] \.”了。因此，应该是前面几种情况，后面跟个”.”字符，正确是：([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\. ，这样就达到要求了。我们会发现，实际上每家一个()字符，都一个子匹配，会在匹配结果里面出现()内容。这里我们加()目的是，让优先计算，因此不需要里面子匹配内容。我们可以加忽略子匹配内容字符：?: ，结果将变为：(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\. </p>
<p>4.一段已经匹配到了，然后我们这样需要重复三次，我们可以直接重复上一个表达式3次：</p>
<p>方法一：(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.</p>
<p>方法二：把第一段作为分组，重复3次&#160;&#160;&#160; ((?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3} ，然后同样忽略子匹配结果，可以变为：</p>
<p>(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3} 哈哈，看到这个表达式是不是很晕了，其实一个长的表达式，都是从一点一点加上去的。这个利用到，重复次数，将结果简化不少了。</p>
<p>5.最后还有一段0-255匹配</p>
<p>(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]) ，也就是在后面加多一个0-255匹配即可，然后在上面再加上头尾限定符，变成了：^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$</p>
<p>下面一个图，是读一段文字里面，所有IP个格式地址</p>
<blockquote><p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image12.png"><img style="background-image: none; border-right-width: 0px; margin: 0px 0px 0px 10px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb12.png" width="896" height="379" /></a></p>
<p>其中(?=……)是正向匹配，搜索左边字符串，并且该字符串右边必须满足?=后面匹配成功的才匹配成功！</p>
</blockquote>
<p>&#160;</p>
<p>好了，写了这么些例子，发现一口气能从很简单正则表达式，匹配到这么长的表达式了。是不是感觉有些晕了，其实不奇怪，长的正则表达式都是从简单正则表达式得到。逐步加上去了。 欢迎讨论交流！</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/190.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>正则表达式（regex)或操作符&#8221;&#124;&#8220;使用易出现功能Bug</title>
		<link>http://blog.chacuo.net/187.html</link>
		<comments>http://blog.chacuo.net/187.html#comments</comments>
		<pubDate>Sun, 09 Jun 2013 11:05:27 +0000</pubDate>
		<dc:creator>程默</dc:creator>
				<category><![CDATA[web原理]]></category>
		<category><![CDATA[学习心得]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[正则表达式]]></category>

		<guid isPermaLink="false">http://blog.chacuo.net/?p=187</guid>
		<description><![CDATA[接上一篇：正则表达式（regex)错误使用导致功能漏洞 ，我们继续梳理，正则表达式错误使用，导致功能设计漏洞（ [...]]]></description>
				<content:encoded><![CDATA[<p>接上一篇：<a href="http://blog.chacuo.net/183.html">正则表达式（regex)错误使用导致功能漏洞</a> ，我们继续梳理，<strong>正则表达式</strong>错误使用，导致功能设计漏洞（bug），做web方面，需要掌握的知识很多，网站开发这项工作，在国内也就10多年，很多开发人员，都是通过：培训(自学) -&gt;模仿-&gt;做项目 ，这样一个过程。很多就是修修改改后，就成为了web开发工程师。这行入门低，很容易上手。但是想成为大师级的，还是很不容易。需要学习，掌握的知识几十门。而对于刚刚入门同人，很多时候因为缺乏系统学习，理论支持。导致提升有些心有余而力不足啦！因此，出现这些或多或少的功能设计漏洞，是很常见的！</p>
<p>好了，有些跑题了，在做代码走查时候，这类漏洞也是时常出现。我们看下，下面代码：</p>
<blockquote>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="php" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">&lt;?php</span>
<span style="color: #000088;">$user</span><span style="color: #339933;">=</span><span style="color: #0000ff;">&quot;bcd123张三&quot;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">///匹配用户名中出现abc还有bcd开头，后面紧跟是数字字符</span>
&nbsp;
<span style="color: #990000;">preg_match_all</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;/abc|bcd\d+/&quot;</span><span style="color: #339933;">,</span><span style="color: #000088;">$user</span><span style="color: #339933;">,</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #990000;">var_dump</span><span style="color: #009900;">&#40;</span><span style="color: #000088;">$match</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">/*结果是
array(1) {
  [0]=&gt;
  array(1) {
    [0]=&gt;
    string(6) &quot;bcd123&quot;
  }
}
*/</span></pre></td></tr></table></div>

<p>查找所有页面出现abc或者bcd开头，后面紧跟数字字符串。通过上面，我们看，正确匹配到bcd123，如果我们输入:$user = “abc123张三”， 发现不能匹配到了。原因是”|”字符，优先级最低，以上写法会变成：匹配abc 或者是bcd\d+ 字符串。</p>
<p><a href="http://blog.chacuo.net/wp-content/uploads/2013/06/image11.png"><img style="border-bottom: 0px; border-left: 0px; display: inline; border-top: 0px; border-right: 0px" title="image" border="0" alt="image" src="http://blog.chacuo.net/wp-content/uploads/2013/06/image_thumb11.png" width="714" height="309" /></a> </p>
<p>以上图，将|，包含到()中。</p>
</blockquote>
<p>&#160;</p>
<p>如果要提升优先级，可以(abc|bcd)\d+ ，匹配所有abc或者bcd 字符串，并且后面紧跟数字的。在使用”|”字符串，注意它的优先级级别低，如果要优先匹配，可以放入（）中。</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.chacuo.net/187.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
