﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-lsbwahaha-随笔分类-J2EE </title><link>http://www.blogjava.net/lsbwahaha/category/39210.html</link><description /><language>zh-cn</language><lastBuildDate>Sun, 30 Oct 2011 07:53:53 GMT</lastBuildDate><pubDate>Sun, 30 Oct 2011 07:53:53 GMT</pubDate><ttl>60</ttl><item><title>java的4种Reference探讨</title><link>http://www.blogjava.net/lsbwahaha/archive/2011/10/30/362314.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Sun, 30 Oct 2011 03:59:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2011/10/30/362314.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/362314.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2011/10/30/362314.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/362314.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/362314.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: java中的引用分为4种：String Reference， WeakReference， softReference，PhantomReference   &nbsp;Strong Reference:  我们平常用的最多的就是强引用了 如：String&nbsp;s = new String("opps");这种形式的引用称为强引用，这种引用有以下几个特点   1.强引用可以直接访问目标对象&...&nbsp;&nbsp;<a href='http://www.blogjava.net/lsbwahaha/archive/2011/10/30/362314.html'>阅读全文</a><img src ="http://www.blogjava.net/lsbwahaha/aggbug/362314.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2011-10-30 11:59 <a href="http://www.blogjava.net/lsbwahaha/archive/2011/10/30/362314.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>理解java中的ThreadLocal</title><link>http://www.blogjava.net/lsbwahaha/archive/2011/10/29/362282.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Sat, 29 Oct 2011 09:39:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2011/10/29/362282.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/362282.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2011/10/29/362282.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/362282.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/362282.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;一、对ThreadLocal概术&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JDK API 写道：该类提供了线程局部 (thread-local) 变量。这些变量不同于它们的普通对应物，因为访问某个变量（通过其 get 或 set 方法）的每个线程都有自己的局部变量，它独立于变量的初始...&nbsp;&nbsp;<a href='http://www.blogjava.net/lsbwahaha/archive/2011/10/29/362282.html'>阅读全文</a><img src ="http://www.blogjava.net/lsbwahaha/aggbug/362282.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2011-10-29 17:39 <a href="http://www.blogjava.net/lsbwahaha/archive/2011/10/29/362282.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>TrueZIP使用过程中遇到的问题记录</title><link>http://www.blogjava.net/lsbwahaha/archive/2011/01/11/342800.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Tue, 11 Jan 2011 14:30:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2011/01/11/342800.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/342800.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2011/01/11/342800.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/342800.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/342800.html</trackback:ping><description><![CDATA[&nbsp;
<p>最近有Java解压缩的需求，java.util.zip实在不好用，对中文支持也不行。所以选择了强大的TrueZIP，使用时遇到了一个问题，做个记录。<br />
解压缩代码如下：</p>
<pre><span style="font-family: 'Courier New'">ArchiveDetector detector <span style="color: #339933">=</span> <strong><span style="color: black">new</span></strong> DefaultArchiveDetector<span style="color: #009900">(</span>ArchiveDetector.<span style="color: #006633">ALL</span>,</span></pre>
<pre><span style="font-family: 'Courier New'">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong><span style="color: black">new</span></strong> <span style="color: #003399">Object</span><span style="color: #009900">[]</span> <span style="color: #009900">{</span> <span style="color: blue">"zip"</span>, <strong><span style="color: black">new</span></strong> CheckedZip32Driver<span style="color: #009900">(</span><span style="color: blue">"GBK"</span><span style="color: #009900">)</span> <span style="color: #009900">}</span> <span style="color: #009900">)</span><span style="color: #339933">;</span></span></pre>
<pre><span style="font-family: 'Courier New'; color: #003399">File</span><span style="font-family: 'Courier New'"> zipFile <span style="color: #339933">=</span> <strong><span style="color: black">new</span></strong> <span style="color: #003399">File</span><span style="color: #009900">(</span><span style="color: blue">"zipFile"</span>, detector<span style="color: #009900">)</span><span style="color: #339933">;</span></span></pre>
<pre><span style="font-family: 'Courier New'; color: #003399">File</span><span style="font-family: 'Courier New'"> dst <span style="color: #339933">=</span> <strong><span style="color: black">new</span></strong> <span style="color: #003399">File</span><span style="color: #009900">(</span><span style="color: blue">"dst"</span><span style="color: #009900">)</span><span style="color: #339933">;</span></span></pre>
<pre><em><span style="font-family: 'Courier New'; color: #666666">// </span></em><em><span style="color: #666666">解压缩</span></em></pre>
<pre><span style="font-family: 'Courier New'">zipFile.<span style="color: #006633">copyAllTo</span><span style="color: #009900">(</span>dst<span style="color: #009900">)</span><span style="color: #339933">;</span></span></pre>
<p>代码十分简洁，注意这个File是</p>
<pre><span style="font-family: 'Courier New'">de.<span style="color: #006633">schlichtherle</span>.<span style="color: #006633">io</span>.<span style="color: #003399">File</span></span></pre>
<p>不是</p>
<pre><span style="font-family: 'Courier New'">java.<span style="color: #006633">io</span>.<span style="color: #003399">File</span></span></pre>
<p>当处理完业务要删除这个Zip File时，问题出现了：<br />
这个文件删不掉！！！<br />
把自己的代码检查了好久，确认没问题后，开始从TrueZIP下手，发现它有特殊的地方的，是提示过的：</p>
<p>File file = new File(&#8220;archive.zip&#8221;); // de.schlichtherle.io.File!<br />
Please do not do this instead:<br />
de.schlichtherle.io.File file = new de.schlichtherle.io.File(&#8220;archive.zip&#8221;);</p>
<p><br />
This is for the following reasons:<br />
1.Accidentally using java.io.File and de.schlichtherle.io.File instances referring to the same path concurrently will result in erroneous behaviour and may even cause loss of data! Please refer to the section &#8220;Third Party Access&#8221; in the package Javadoc of de.schlichtherle.io for for full details and workarounds.<br />
2.A de.schlichtherle.io.File subclasses java.io.File and thanks to polymorphism can be used everywhere a java.io.File could be used. </p>
<p>原来两个File不能交叉使用，搞清楚原因了，加这么一句代码搞定。</p>
<pre><span style="font-family: 'Courier New'">zipFile.<span style="color: #006633">deleteAll</span><span style="color: #009900">()</span><span style="color: #339933">;<br />
<br />
</span></span></pre>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/342800.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2011-01-11 22:30 <a href="http://www.blogjava.net/lsbwahaha/archive/2011/01/11/342800.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>用linkList实现LRU算法</title><link>http://www.blogjava.net/lsbwahaha/archive/2010/08/15/328918.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Sun, 15 Aug 2010 12:33:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2010/08/15/328918.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/328918.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2010/08/15/328918.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/328918.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/328918.html</trackback:ping><description><![CDATA[<p>public class LRUCache&lt;K,V&gt; {</p>
<p>&nbsp;&nbsp;&nbsp; final private int capacity;<br />
&nbsp;&nbsp;&nbsp; final private Map&lt;K,Reference&lt;V&gt;&gt; map;<br />
&nbsp;&nbsp;&nbsp; final private ReentrantLock lock = new ReentrantLock();<br />
&nbsp;&nbsp;&nbsp; final private ReferenceQueue&lt;Reference&lt;V&gt;&gt; queue = new ReferenceQueue&lt;Reference&lt;V&gt;&gt;();<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public LRUCache(int capacity) {<br />
&nbsp;this.capacity = capacity;<br />
&nbsp;map = new LinkedHashMap&lt;K,Reference&lt;V&gt;&gt;(capacity,1f,true){<br />
&nbsp;&nbsp;&nbsp;&nbsp; @Override<br />
&nbsp;&nbsp;&nbsp;&nbsp; protected boolean removeEldestEntry(Map.Entry&lt;K,Reference&lt;V&gt;&gt; eldest) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.size() &gt; LRUCache.this.capacity;<br />
&nbsp;&nbsp;&nbsp;&nbsp; }<br />
&nbsp;};<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public V put(K key,V value) {<br />
&nbsp;lock.lock();<br />
&nbsp;try {<br />
&nbsp; map.put(key, new SoftReference(value,queue));<br />
&nbsp; return value;<br />
&nbsp;}finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp; lock.unlock();<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; public V get(K key) {<br />
&nbsp;lock.lock();<br />
&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp; queue.poll();<br />
&nbsp;&nbsp;&nbsp;&nbsp; return map.get(key).get();<br />
&nbsp;}finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp; lock.unlock();<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp; }<br />
&nbsp;<br />
&nbsp;&nbsp;&nbsp; public void remove(K key) {<br />
&nbsp;lock.lock();<br />
&nbsp;try {<br />
&nbsp;&nbsp;&nbsp;&nbsp; map.remove(key);<br />
&nbsp;}finally {<br />
&nbsp;&nbsp;&nbsp;&nbsp; lock.unlock();<br />
&nbsp;}<br />
&nbsp;&nbsp;&nbsp; }</p>
<p>}</p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/328918.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2010-08-15 20:33 <a href="http://www.blogjava.net/lsbwahaha/archive/2010/08/15/328918.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Unicode简介(转)</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/05/16/270963.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Fri, 15 May 2009 17:52:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/05/16/270963.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/270963.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/05/16/270963.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/270963.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/270963.html</trackback:ping><description><![CDATA[<br />
Unicode是一种字符编码规范&nbsp;。<br />
<br />
先从ASCII说起。ASCII是用来表示英文字符的一种编码规范，每个ASCII字符占用1个字节（8bits）&nbsp;<br />
<br />
因此，ASCII编码可以表示的最大字符数是256，其实英文字符并没有那么多，一般只用前128个（最高位为0），其中包括了控制字符、数字、大小写字母和其他一些符号&nbsp;。<br />
<br />
而最高位为1的另128个字符被成为&#8220;扩展ASCII&#8221;，一般用来存放英文的制表符、部分音标字符等等的一些其他符号&nbsp;<br />
<br />
这种字符编码规范显然用来处理英文没有什么问题&nbsp;。（实际上也可以用来处理法文、德文等一些其他的西欧字符，但是不能和英文通用），但是面对中文、阿拉伯文之类复杂的文字，255个字符显然不够用&nbsp;<br />
<br />
于是，各个国家纷纷制定了自己的文字编码规范，其中中文的文字编码规范叫做&#8220;GB2312-80&#8221;，它是和ASCII兼容的一种编码规范，其实就是利用扩展ASCII没有真正标准化这一点，把一个中文字符用两个扩展ASCII字符来表示。&nbsp;<br />
<br />
但是这个方法有问题，最大的问题就是，中文文字没有真正属于自己的编码，因为扩展ASCII码虽然没有真正的标准化，但是PC里的ASCII码还是有一个事实标准的（存放着英文制表符），所以很多软件利用这些符号来画表格。这样的软件用到中文系统中，这些表格符就会被误认作中文字，破坏版面。而且，统计中英文混合字符串中的字数，也是比较复杂的，我们必须判断一个ASCII码是否扩展，以及它的下一个ASCII是否扩展，然后才&#8220;猜&#8221;那可能是一个中文字&nbsp;。<br />
<br />
总之当时处理中文是很痛苦的。而更痛苦的是GB2312是国家标准，台湾当时有一个Big5编码标准，很多编码和GB是相同的，所以&#8230;&#8230;，嘿嘿。&nbsp;<br />
<br />
这时候，我们就知道，要真正解决中文问题，不能从扩展ASCII的角度入手，也不能仅靠中国一家来解决。而必须有一个全新的编码系统，这个系统要可以将中文、英文、法文、德文&#8230;&#8230;等等所有的文字统一起来考虑，为每个文字都分配一个单独的编码，这样才不会有上面那种现象出现。&nbsp;<br />
<br />
于是，Unicode诞生了。&nbsp;<br />
<br />
Unicode有两套标准，一套叫UCS-2(Unicode-16)，用2个字节为字符编码，另一套叫UCS-4(Unicode-32)，用4个字节为字符编码。&nbsp;<br />
<br />
以目前常用的UCS-2为例，它可以表示的字符数为2^16=65535，基本上可以容纳所有的欧美字符和绝大部分的亚洲字符&nbsp;。<br />
<br />
UTF-8的问题后面会提到&nbsp;。<br />
<br />
在Unicode里，所有的字符被一视同仁。汉字不再使用&#8220;两个扩展ASCII&#8221;，而是使用&#8220;1个Unicode&#8221;，注意，现在的汉字是&#8220;一个字符&#8221;了，于是，拆字、统计字数这些问题也就自然而然的解决了&nbsp;。<br />
<br />
但是，这个世界不是理想的，不可能在一夜之间所有的系统都使用Unicode来处理字符，所以Unicode在诞生之日，就必须考虑一个严峻的问题：和ASCII字符集之间的不兼容问题。&nbsp;<br />
<br />
我们知道，ASCII字符是单个字节的，比如&#8220;A&#8221;的ASCII是65。而Unicode是双字节的，比如&#8220;A&#8221;的Unicode是0065，这就造成了一个非常大的问题：以前处理ASCII的那套机制不能被用来处理Unicode了&nbsp;。<br />
<br />
另一个更加严重的问题是，C语言使用'\0'作为字符串结尾，而Unicode里恰恰有很多字符都有一个字节为0，这样一来，C语言的字符串函数将无法正常处理Unicode，除非把世界上所有用C写的程序以及他们所用的函数库全部换掉&nbsp;。<br />
<br />
于是，比Unicode更伟大的东东诞生了，之所以说它更伟大是因为它让Unicode不再存在于纸上，而是真实的存在于我们大家的电脑中。那就是：UTF&nbsp;。<br />
<br />
UTF=&nbsp;UCS&nbsp;Transformation&nbsp;Format&nbsp;UCS转换格式&nbsp;<br />
<br />
它是将Unicode编码规则和计算机的实际编码对应起来的一个规则。现在流行的UTF有2种：UTF-8和UTF-16&nbsp;。<br />
<br />
其中UTF-16和上面提到的Unicode本身的编码规范是一致的，这里不多说了。而UTF-8不同，它定义了一种&#8220;区间规则&#8221;，这种规则可以和ASCII编码保持最大程度的兼容&nbsp;。<br />
<br />
UTF-8有点类似于Haffman编码，它将Unicode编码为00000000-0000007F的字符，用单个字节来表示；&nbsp;<br />
<br />
00000080-000007FF的字符用两个字节表示&nbsp;<br />
<br />
00000800-0000FFFF的字符用3字节表示&nbsp;<br />
<br />
因为目前为止Unicode-16规范没有指定FFFF以上的字符，所以UTF-8最多是使用3个字节来表示一个字符。但理论上来说，UTF-8最多需要用6字节表示一个字符。&nbsp;<br />
<br />
在UTF-8里，英文字符仍然跟ASCII编码一样，因此原先的函数库可以继续使用。而中文的编码范围是在0080-07FF之间，因此是2个字节表示（但这两个字节和GB编码的两个字节是不同的），用专门的Unicode处理类可以对UTF编码进行处理。&nbsp;<br />
<br />
下面说说中文的问题。&nbsp;<br />
<br />
由于历史的原因，在Unicode之前，一共存在过3套中文编码标准。&nbsp;<br />
<br />
GB2312-80，是中国大陆使用的国家标准，其中一共编码了6763个常用简体汉字。Big5，是台湾使用的编码标准，编码了台湾使用的繁体汉字，大概有8千多个。HKSCS，是中国香港使用的编码标准，字体也是繁体，但跟Big5有所不同。&nbsp;<br />
<br />
这3套编码标准都采用了两个扩展ASCII的方法，因此，几套编码互不兼容，而且编码区间也各有不同&nbsp;<br />
<br />
因为其不兼容性，在同一个系统中同时显示GB和Big5基本上是不可能的。当时的南极星、RichWin等等软件，在自动识别中文编码、自动显示正确编码方面都做了很多努力&nbsp;。<br />
<br />
他们用了怎样的技术我就不得而知了，我知道好像南极星曾经以同屏显示繁简中文为卖点。&nbsp;<br />
<br />
后来，由于各方面的原因，国际上又制定了针对中文的统一字符集GBK和GB18030，其中GBK已经在Windows、Linux等多种操作系统中被实现。&nbsp;<br />
<br />
GBK兼容GB2312，并增加了大量不常用汉字，还加入了几乎所有的Big5中的繁体汉字。但是GBK中的繁体汉字和Big5中的几乎不兼容。&nbsp;<br />
<br />
GB18030相当于是GBK的超集，比GBK包含的字符更多。据我所知目前还没有操作系统直接支持GB18030。&nbsp;<br />
<br />
<br />
谈谈Unicode编码，简要解释UCS、UTF、BMP、BOM等名词&nbsp;<br />
这是一篇程序员写给程序员的趣味读物。所谓趣味是指可以比较轻松地了解一些原来不清楚的概念，增进知识，类似于打RPG游戏的升级。整理这篇文章的动机是两个问题：<br />
<br />
问题一：&nbsp;<br />
使用Windows记事本的&#8220;另存为&#8221;，可以在GBK、Unicode、Unicode&nbsp;big&nbsp;endian和UTF-8这几种编码方式间相互转换。同样是txt文件，Windows是怎样识别编码方式的呢？<br />
<br />
我很早前就发现Unicode、Unicode&nbsp;big&nbsp;endian和UTF-8编码的txt文件的开头会多出几个字节，分别是FF、FE（Unicode）,FE、FF（Unicode&nbsp;big&nbsp;endian）,EF、BB、BF（UTF-8）。但这些标记是基于什么标准呢？<br />
<br />
问题二：&nbsp;<br />
最近在网上看到一个ConvertUTF.c，实现了UTF-32、UTF-16和UTF-8这三种编码方式的相互转换。对于Unicode(UCS2)、GBK、UTF-8这些编码方式，我原来就了解。但这个程序让我有些糊涂，想不起来UTF-16和UCS2有什么关系。&nbsp;<br />
查了查相关资料，总算将这些问题弄清楚了，顺带也了解了一些Unicode的细节。写成一篇文章，送给有过类似疑问的朋友。本文在写作时尽量做到通俗易懂，但要求读者知道什么是字节，什么是十六进制。<br />
<br />
0、big&nbsp;endian和little&nbsp;endian<br />
big&nbsp;endian和little&nbsp;endian是CPU处理多字节数的不同方式。例如&#8220;汉&#8221;字的Unicode编码是6C49。那么写到文件里时，究竟是将6C写在前面，还是将49写在前面？如果将6C写在前面，就是big&nbsp;endian。还是将49写在前面，就是little&nbsp;endian。<br />
<br />
&#8220;endian&#8221;这个词出自《格列佛游记》。小人国的内战就源于吃鸡蛋时是究竟从大头(Big-Endian)敲开还是从小头(Little-Endian)敲开，由此曾发生过六次叛乱，其中一个皇帝送了命，另一个丢了王位。<br />
<br />
我们一般将endian翻译成&#8220;字节序&#8221;，将big&nbsp;endian和little&nbsp;endian称作&#8220;大尾&#8221;和&#8220;小尾&#8221;。<br />
<br />
1、字符编码、内码，顺带介绍汉字编码<br />
字符必须编码后才能被计算机处理。计算机使用的缺省编码方式就是计算机的内码。早期的计算机使用7位的ASCII编码，为了处理汉字，程序员设计了用于简体中文的GB2312和用于繁体中文的big5。<br />
<br />
GB2312(1980年)一共收录了7445个字符，包括6763个汉字和682个其它符号。汉字区的内码范围高字节从B0-F7，低字节从A1-FE，占用的码位是72*94=6768。其中有5个空位是D7FA-D7FE。<br />
<br />
GB2312支持的汉字太少。1995年的汉字扩展规范GBK1.0收录了21886个符号，它分为汉字区和图形符号区。汉字区包括21003个字符。2000年的GB18030是取代GBK1.0的正式国家标准。该标准收录了27484个汉字，同时还收录了藏文、蒙文、维吾尔文等主要的少数民族文字。现在的PC平台必须支持GB18030，对嵌入式产品暂不作要求。所以手机、MP3一般只支持GB2312。<br />
<br />
从ASCII、GB2312、GBK到GB18030，这些编码方法是向下兼容的，即同一个字符在这些方案中总是有相同的编码，后面的标准支持更多的字符。在这些编码中，英文和中文可以统一地处理。区分中文编码的方法是高字节的最高位不为0。按照程序员的称呼，GB2312、GBK到GB18030都属于双字节字符集&nbsp;(DBCS)。<br />
<br />
有的中文Windows的缺省内码还是GBK，可以通过GB18030升级包升级到GB18030。不过GB18030相对GBK增加的字符，普通人是很难用到的，通常我们还是用GBK指代中文Windows内码。<br />
<br />
这里还有一些细节：<br />
<br />
GB2312的原文还是区位码，从区位码到内码，需要在高字节和低字节上分别加上A0。<br />
<br />
在DBCS中，GB内码的存储格式始终是big&nbsp;endian，即高位在前。<br />
<br />
GB2312的两个字节的最高位都是1。但符合这个条件的码位只有128*128=16384个。所以GBK和GB18030的低字节最高位都可能不是1。不过这不影响DBCS字符流的解析：在读取DBCS字符流时，只要遇到高位为1的字节，就可以将下两个字节作为一个双字节编码，而不用管低字节的高位是什么。<br />
<br />
2、Unicode、UCS和UTF<br />
前面提到从ASCII、GB2312、GBK到GB18030的编码方法是向下兼容的。而Unicode只与ASCII兼容（更准确地说，是与ISO-8859-1兼容），与GB码不兼容。例如&#8220;汉&#8221;字的Unicode编码是6C49，而GB码是BABA。<br />
<br />
Unicode也是一种字符编码方法，不过它是由国际组织设计，可以容纳全世界所有语言文字的编码方案。Unicode的学名是"Universal&nbsp;Multiple-Octet&nbsp;Coded&nbsp;Character&nbsp;Set"，简称为UCS。UCS可以看作是"Unicode&nbsp;Character&nbsp;Set"的缩写。<br />
<br />
根据维基百科全书(<a href="http://zh.wikipedia.org/wiki/">http://zh.wikipedia.org/wiki/</a>)的记载：历史上存在两个试图独立设计Unicode的组织，即国际标准化组织（ISO）和一个软件制造商的协会（unicode.org）。ISO开发了ISO&nbsp;10646项目，Unicode协会开发了Unicode项目。<br />
<br />
在1991年前后，双方都认识到世界不需要两个不兼容的字符集。于是它们开始合并双方的工作成果，并为创立一个单一编码表而协同工作。从Unicode2.0开始，Unicode项目采用了与ISO&nbsp;10646-1相同的字库和字码。<br />
<br />
目前两个项目仍都存在，并独立地公布各自的标准。Unicode协会现在的最新版本是2005年的Unicode&nbsp;4.1.0。ISO的最新标准是10646-3:2003。<br />
<br />
UCS规定了怎么用多个字节表示各种文字。怎样传输这些编码，是由UTF(UCS&nbsp;Transformation&nbsp;Format)规范规定的，常见的UTF规范包括UTF-8、UTF-7、UTF-16。<br />
<br />
IETF的RFC2781和RFC3629以RFC的一贯风格，清晰、明快又不失严谨地描述了UTF-16和UTF-8的编码方法。我总是记不得IETF是Internet&nbsp;Engineering&nbsp;Task&nbsp;Force的缩写。但IETF负责维护的RFC是Internet上一切规范的基础。<br />
<br />
3、UCS-2、UCS-4、BMP<br />
<br />
UCS有两种格式：UCS-2和UCS-4。顾名思义，UCS-2就是用两个字节编码，UCS-4就是用4个字节（实际上只用了31位，最高位必须为0）编码。下面让我们做一些简单的数学游戏：<br />
<br />
UCS-2有2^16=65536个码位，UCS-4有2^31=2147483648个码位。<br />
<br />
UCS-4根据最高位为0的最高字节分成2^7=128个group。每个group再根据次高字节分为256个plane。每个plane根据第3个字节分为256行&nbsp;(rows)，每行包含256个cells。当然同一行的cells只是最后一个字节不同，其余都相同。<br />
<br />
group&nbsp;0的plane&nbsp;0被称作Basic&nbsp;Multilingual&nbsp;Plane,&nbsp;即BMP。或者说UCS-4中，高两个字节为0的码位被称作BMP。<br />
<br />
将UCS-4的BMP去掉前面的两个零字节就得到了UCS-2。在UCS-2的两个字节前加上两个零字节，就得到了UCS-4的BMP。而目前的UCS-4规范中还没有任何字符被分配在BMP之外。<br />
<br />
4、UTF编码<br />
<br />
UTF-8就是以8位为单元对UCS进行编码。从UCS-2到UTF-8的编码方式如下：<br />
<br />
UCS-2编码(16进制)&nbsp;UTF-8&nbsp;字节流(二进制)&nbsp;<br />
0000&nbsp;-&nbsp;007F&nbsp;0xxxxxxx&nbsp;<br />
0080&nbsp;-&nbsp;07FF&nbsp;110xxxxx&nbsp;10xxxxxx&nbsp;<br />
0800&nbsp;-&nbsp;FFFF&nbsp;1110xxxx&nbsp;10xxxxxx&nbsp;10xxxxxx&nbsp;<br />
<br />
例如&#8220;汉&#8221;字的Unicode编码是6C49。6C49在0800-FFFF之间，所以肯定要用3字节模板了：1110xxxx&nbsp;10xxxxxx&nbsp;10xxxxxx。将6C49写成二进制是：0110&nbsp;110001&nbsp;001001，&nbsp;用这个比特流依次代替模板中的x，得到：11100110&nbsp;10110001&nbsp;10001001，即E6&nbsp;B1&nbsp;89。<br />
<br />
读者可以用记事本测试一下我们的编码是否正确。<br />
<br />
UTF-16以16位为单元对UCS进行编码。对于小于0x10000的UCS码，UTF-16编码就等于UCS码对应的16位无符号整数。对于不小于0x10000的UCS码，定义了一个算法。不过由于实际使用的UCS2，或者UCS4的BMP必然小于0x10000，所以就目前而言，可以认为UTF-16和UCS-2基本相同。但UCS-2只是一个编码方案，UTF-16却要用于实际的传输，所以就不得不考虑字节序的问题。<br />
<br />
5、UTF的字节序和BOM<br />
UTF-8以字节为编码单元，没有字节序的问题。UTF-16以两个字节为编码单元，在解释一个UTF-16文本前，首先要弄清楚每个编码单元的字节序。例如收到一个&#8220;奎&#8221;的Unicode编码是594E，&#8220;乙&#8221;的Unicode编码是4E59。如果我们收到UTF-16字节流&#8220;594E&#8221;，那么这是&#8220;奎&#8221;还是&#8220;乙&#8221;？<br />
<br />
Unicode规范中推荐的标记字节顺序的方法是BOM。BOM不是&#8220;Bill&nbsp;Of&nbsp;Material&#8221;的BOM表，而是Byte&nbsp;Order&nbsp;Mark。BOM是一个有点小聪明的想法：<br />
<br />
在UCS编码中有一个叫做"ZERO&nbsp;WIDTH&nbsp;NO-BREAK&nbsp;SPACE"的字符，它的编码是FEFF。而FFFE在UCS中是不存在的字符，所以不应该出现在实际传输中。UCS规范建议我们在传输字节流前，先传输字符"ZERO&nbsp;WIDTH&nbsp;NO-BREAK&nbsp;SPACE"。<br />
<br />
这样如果接收者收到FEFF，就表明这个字节流是Big-Endian的；如果收到FFFE，就表明这个字节流是Little-Endian的。因此字符"ZERO&nbsp;WIDTH&nbsp;NO-BREAK&nbsp;SPACE"又被称作BOM。<br />
<br />
UTF-8不需要BOM来表明字节顺序，但可以用BOM来表明编码方式。字符"ZERO&nbsp;WIDTH&nbsp;NO-BREAK&nbsp;SPACE"的UTF-8编码是EF&nbsp;BB&nbsp;BF（读者可以用我们前面介绍的编码方法验证一下）。所以如果接收者收到以EF&nbsp;BB&nbsp;BF开头的字节流，就知道这是UTF-8编码了。<br />
<br />
Windows就是使用BOM来标记文本文件的编码方式的。<br />
<br />
6、进一步的参考资料<br />
本文主要参考的资料是&nbsp;"Short&nbsp;overview&nbsp;of&nbsp;ISO-IEC&nbsp;10646&nbsp;and&nbsp;Unicode"&nbsp;(<a href="http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html">http://www.nada.kth.se/i18n/ucs/unicode-iso10646-oview.html</a>)。<br />
<br />
我还找了两篇看上去不错的资料，不过因为我开始的疑问都找到了答案，所以就没有看：<br />
<br />
"Understanding&nbsp;Unicode&nbsp;A&nbsp;general&nbsp;introduction&nbsp;to&nbsp;the&nbsp;Unicode&nbsp;Standard"&nbsp;(<a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter04a">http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter04a</a>)&nbsp;<br />
"Character&nbsp;set&nbsp;encoding&nbsp;basics&nbsp;Understanding&nbsp;character&nbsp;set&nbsp;encodings&nbsp;and&nbsp;legacy&nbsp;encodings"&nbsp;(<a href="http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter03">http://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&amp;item_id=IWS-Chapter03</a>)<br />
<br />
<br />
<script type="text/javascript"><!-- google_ad_client="pub-7390275636631344" ; google_ad_width="728;
google_ad_height" = 90; google_ad_format="728x90_as" ; google_ad_type="text_image" ; google_ad_channel="5095444487" ; google_color_border="336699" ; google_color_bg="FFFFFF" ; google_color_link="0000FF" ; google_color_url="008000" ; google_color_text="000000" ;
//--></script><script src="JR - 精品文章 - Unicode简介(UTF-8和GB2312,GBK,GB10830的关系可以看看).files/show_ads.js" type="text/javascript">
</script>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/270963.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-05-16 01:52 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/05/16/270963.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Web2.0下的十大安全威胁(转)</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270952.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Fri, 15 May 2009 15:31:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270952.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/270952.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270952.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/270952.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/270952.html</trackback:ping><description><![CDATA[<font size="2">下面列举10个攻击:</font>
<p><strong><font size="2">　　1.AJAX中的跨站点脚本</font></strong></p>
<p><font size="2">　　前几个月，人们发现了多种跨站点的脚本攻击。在此类攻击中，受害者的包含信息的浏览器上会运行来自特定网站的恶意JAVA脚本代码。
Yamanner蠕虫就是一个最近的范例，它利用Yahoo邮件的AJAX调用中的跨站点脚本机会来攻击受害者。另一个近期的范例就是Samy蠕虫，它利
用MySpace.com的跨站点脚本漏洞来攻击。AJAX在客户端上运行，它允许错误书写的脚本被攻击者利用。攻击者能够编写恶意链接来哄骗那些没有准
备的用户，让他们用浏览器去访问特定的网页。传统应用中也存在这样的弱点，但AJAX给它添加了更多可能的漏洞。<font color="#ff0000">例子， Yamanner蠕虫利用了Yahoo
Mail的AJAX的跨站脚本漏洞，Samy蠕虫利用了MySpace.com的跨站脚本漏洞。</font> </font></p>
<p><font size="2">　<strong>　2.XML中毒</strong></font></p>
<p><font size="2">　　很多Web2.0应用中，XML传输在服务器和浏览器之间往复。网络应用接收来自AJAX客户端的XML块。这XML块很可能染毒。多次将递归
负载应用到产出相似的XML节点,这样的技术还并不普遍。如果机器的处理能力较弱，这将导致服务器拒绝服务。很多攻击者还制作结构错误的XML文档，这些
文档会扰乱服务器上所使用的依赖剖析机制的逻辑。服务器端的剖析机制有两种类型，它们是SAX和DOM。网络服务也使用相同的攻击向量，这是因为网络服务
接收SOAP消息，而SOAP就是XML消息。在应用层大范围地使用XMLs使攻击者有更多的机会利用这个新的攻击向量。</font></p>
<p><font size="2">　　XML外部实体参照是能被攻击者伪造的一个XML的属性。这会使攻击者能够利用人意的文件或者TCP连接的缺陷。XML
schema中毒是另一个XML中毒的攻击向量，它能够改变执行的流程。这个漏洞能帮助攻击者获得机密信息。<font color="#ff0000">攻击者可以通过复制节点进行DOS攻击，或者生成不合法的XML导致服务器端逻辑的中断。攻击者也可以操纵外部实体，导致打开任何文件或TCP连接端口。XML数据定义的中毒也可以导致运行流程的改变，助攻击者获取机密信息。</font>
</font></p>
<p><strong><font size="2">　　3.恶意AJAX代码的执行</font></strong></p>
<p><font size="2">　　AJAX调用非常不易察觉，终端用户无法确定浏览器是否正在用XMLHTTP请求对象发出无记载的调用。浏览器发出AJAX调用给任意网站的时
候，该网站会对每个请求回应以cookies。这将导致出现泄漏的潜在可能性。例如，约翰已经登陆了他的银行，并且通过了服务器认证。完成认证过程后，他
会得到一个会话
cookie。银行的页面中包含了很多关键信息。现在，他去浏览器他网页，并同时仍然保持银行账户的登陆状态。他可能会刚好访问一个攻击者的网页，在这个
网页上攻击者写了不易被察觉的AJAX
代码，这个代码不用经过约翰的同意，就能够发出后台调用给约翰的银行网页，因而能够从银行页面取得关键信息并且把这些信息发送到攻击者的网站。这将导致机
密信息的泄漏甚至引发安全突破。<font color="#ff0000">AJAX
编码可以在不为用户所知的情形下运行，假如用户先登录一个机密网站，机密网站返回一个会话cookie，然后用户在没有退出机密网站的情形下，访问攻击者
的网站，攻击者网页上的AJAX编码可以(通过这个会话cookie?)去访问机密网站上的网页，从而窃取用户的机密信息。(注：这里的解释有点含糊，理
论上讲，浏览器不会把一个网站的会话cookie传给另外一个网站的，即文中的这句&#8220;When the browser makes an AJAX
call to any Web site it replays cookies for each request. &#8221;，不完全对)</font> </font></p>
<p><strong><font size="2">　　4.RSS/Atom 注入</font></strong></p>
<p><font size="2">
这是一项新的web2.0攻击。RSS反馈是人们在门户网站或者网络应用中共享信息的常用手段。网络应用接受这些反馈然后发送给客户端的浏览器。人们可
以在该RSS反馈中插入文本的JavaScript来产生对用户浏览器的攻击。访问特定网站的终端用户加载了带有该RSS反馈的网页，这个脚本
就会运行起来——它能够往用户的电脑中安装软件或者窃取cookies信息。这就是一个致命的客户端攻击。更糟糕的是，它可以变异。随着RSS和ATOM
反馈成为网络应用中整合的组件，在服务器端将数据发布给终端用户之前，过滤特定字符是非常必要的。<font color="#ff0000">攻击者可以在RSS
feeds里注入Javascript脚本，如果服务器端没有过滤掉这些脚本的话，在浏览器端会造成问题。</font> </font></p>
<p><font size="2">　　<strong>5.WSDL扫描和enumeration</strong></font></p>
<p><font size="2">　　WSDL(网络服务界定语言)是网络服务的一个接口。该文件提供了技术，开放方法，创新形式等等的关键信息。这是非常敏感信息，而且能够帮助人
们决定利用什么弱点来攻击。如果将不必要的功能或者方法一直开着，这会为网络服务造成潜在的灾难。保护WSDL文件或者限定对其的访问是非常重要的。在实
际情况中，很有可能找到一些使用WSDL扫描的一些漏洞。<font color="#ff0000">WSDL提供了Web服务所用的技术，以及外露的方法，调用的模式等信息。假如Web服务对不必要的方法没有禁止的话，攻击者可以通过WSDL扫描找到潜在的攻击点。</font>
</font></p>
<p><font size="2">　　<strong>6.AJAX常规程序中客户端的确认</strong></font></p>
<p><font size="2">　　基于web2.0的应用使用AJAX常规程序来在客户端上进行很多操作，比如客户端数据类型的确认，内容检查，数据域等等。正常情况下，服务端
也应该备份这些客户端检查信息。大部分开发者都没有这么做;他们这样做的理由是，他们假设这样的确认是由AJAX常规程序来负责的。避开基于AJAX的确
认和直接发送POST或者GET请求给那些应用——这些应用是诸如SQL注入,LDAP注入等类随确认进入的攻击主要来源，它们能够攻击网络应用的关键资
源——都是可以做到的。这都增加了能够为攻击者所利用的潜在攻击向量的数量。<font color="#ff0000">假如开发人员只依赖客户端验证，不在服务器端重新验证的话，会导致SQL注入，LDAP注入等等。</font>
</font></p>
<p><font size="2">　　<strong>7.网络服务路由问题</strong></font></p>
<p><font size="2">　　网络服务安全协议包括WS-Routing服务。WS-Routing允许SOAP消息在互联网上各种各样不同的节点中的特别序列中传输。通常
加密的信息在这些节点来回传送。交互的节点中的任意一个被攻击都将致使攻击者能够访问到在两个端点之间传输的SOAP消息。这将造成SOAP消息的严重的
安全泄漏。随着网络应用开始被网络服务框架所采用，攻击者们开始转而利用这些新协议和新的攻击向量。<font color="#ff0000">Web服务安全协议使用WS-Routing服务，假如任何中转站被攻占，SOAP消息可以被截获。</font>
</font></p>
<p><font size="2">　　<strong>8.</strong>SOAP消息的参数操作</font></p>
<p><font size="2">　　网络服务接收信息和来自SOAP消息的变量。修改这些变量是很可能的。例如，&#8220;10&#8221;是SOAP消息中多个节点中的一个。攻击者可以修改点，并
且尝试不同种的注入攻击——比如，SQL,LDAP,XPATH,命令行解释器——并且探索能被他用来掌握及其内部信息的攻击向量。网络服务代码中错误的
或者不够完备的输入确认使网络服务应用易于发生泄漏.这是一个目标指向网络服务所带的网络应用的一项新的攻击向量。<font color="#ff0000">类似于SQL注入，假如对SOAP消息里节点的数据不做验证的话。</font> </font></p>
<p><font size="2">　　<strong>9.SOAP消息中的XPATH注入</strong></font></p>
<p><font size="2">　　XPATH是一种用来查询XML文档的语言，它跟SQL语句很类似:我们提供某些信息(参数)然后从数据库中得到查询结果。很多语言都支持
XPATH
解析的功能。网络应用接收大型XML文档，很多时候这些应用从终端用户和XPATH语句中取得输入量。这些代码的段落对XPATH注入没有什么防御能力。
如果XPATH执行成功，攻击者能够绕过认证机制或者造成机密信息的一些损失。现在人们只知道很少部分的能够被攻击者利用的XPATH的漏洞。阻止这个攻
击向量的唯一方法就是在给XPATH语句传递变量值的时候提供适当的输入确认。<font color="#ff0000">类似于SQL注入，假如对数据不做验证而直接做XPATH查询的话。</font> </font></p>
<p><font size="2">　　<strong>10. RIA瘦客户端二进制的伪造</strong></font></p>
<p><font size="2">　　丰富网络应用(RIA)使用非常丰富的UI要素比如Flash,ActiveX控件或者Applets，它使用这些要素作为网络应用的基本接
口。这个框架存在几个安全问题。其中最主要的一个就是关于会话管理。它是在浏览器中运行的，并且共享相同的会话。同时，由于客户端将下载整个二进制元件到
自己的主机，攻击者就可以颠倒工程的那个二进制文件并且反编译代码。把这些二进制串打包并绕过一些包含在代码中的认证逻辑是有可能实现的。这是
WEB2.0框架下的另一个有趣的攻击向量。<font color="#ff0000">因为Rich Internet
Applications的组件是下载到浏览器本地的，攻击者可以对二进制文件进行逆向工程，反编译编码，通过改动文件，跳过认证逻辑
。</font></font></p>
<p><font size="2">　　<strong>结论</strong></font></p>
<p><font size="2">　　AJAX,RIA以及网络服务是WEB2.0应用空间的三项重要的技术向量。这些技术很有前景，它们带给桌面新的程式，加强了网络应用的整体效
率和效用。随着这些新技术而来的是新的安全问题，忽略这些问题将会导致整个世界发生巨大的灾难。本文中，我们只讨论了10种攻击。但是实际上还有很多其他
的攻击向量。对这些新的攻击向量的最好的防御方法是增加WEB2.0的安全意识，提高代码操作的安全性以及配置的安全性</font></p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/270952.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-05-15 23:31 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270952.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>常用的匹配正则表达式和实例(转)</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270865.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Fri, 15 May 2009 08:06:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270865.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/270865.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270865.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/270865.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/270865.html</trackback:ping><description><![CDATA[<p><br />
匹配中文字符的正则表达式： [\u4e00-\u9fa5] <br />
匹配双字节字符(包括汉字在内)：[^\x00-\xff]<br />
应用：计算字符串的长度（一个双字节字符长度计2，ASCII字符计1）<br />
String.prototype.len=function(){return this.replace([^\x00-\xff]/g,"aa").length;}<br />
匹配空行的正则表达式：\n[\s| ]*\r<br />
匹配HTML标记的正则表达式：/&lt;(.*)&gt;.*&lt;\/\1&gt;|&lt;(.*) \/&gt;/ <br />
匹配首尾空格的正则表达式：(^\s*)|(\s*$)<br />
应用：javascript中没有像vbscript那样的trim函数，我们就可以利用这个表达式来实现，如下：<br />
String.prototype.trim = function()<br />
{ return this.replace(/(^\s*)|(\s*$)/g, "");<br />
} 利用正则表达式分解和转换IP地址：<br />
下面是利用正则表达式匹配IP地址，并将IP地址转换成对应数值的Javascript程序：<br />
function IP2V(ip)<br />
{<br />
re=/(\d+)\.(\d+)\.(\d+)\.(\d+)/g //匹配IP地址的正则表达式<br />
if(re.test(ip))<br />
{<br />
return RegExp.$1*Math.pow(255,3))+RegExp.$2*Math.pow(255,2))+RegExp.$3*255+RegExp.$4*1<br />
}<br />
else<br />
{<br />
throw new Error("Not a valid IP address!")<br />
}<br />
}</p>
<p>不过上面的程序如果不用正则表达式，而直接用split函数来分解可能更简单，程序如下：</p>
<p>var ip="10.100.20.168"<br />
ip=ip.split(".")<br />
alert("IP值是："+(ip[0]*255*255*255+ip[1]*255*255+ip[2]*255+ip[3]*1))</p>
<p>匹配Email地址的正则表达式：\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*</p>
<p>匹配网址URL的正则表达式：http://([\w-]+\.)+[\w-]+(/[\w- ./?%&amp;=]*)?</p>
<p>利用正则表达式限制网页表单里的文本框输入内容：</p>
<p>用正则表达式限制只能输入中文：onkeyup="value=value.replace(/[^\u4E00-\u9FA5]/g,'')" <br />
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\u4E00-\u9FA5]/g,''))" </p>
<p>用正则表达式限制只能输入全角字符： onkeyup="value=value.replace(/[^\uFF00-\uFFFF]/g,'')" <br />
onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\uFF00-\uFFFF]/g,''))"</p>
<p>用正则表达式限制只能输入数字：onkeyup="value=value.replace(/</p>
<p>[^\d]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))"</p>
<p>用正则表达式限制只能输入数字和英文：onkeyup="value=value.replace(/<br />
[\W]/g,'') "onbeforepaste="clipboardData.setData('text',clipboardData.getData('text').replace(/[^\d]/g,''))" </p>
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/270865.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-05-15 16:06 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/05/15/270865.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java获取qq邮箱中的好友列表</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/05/07/269462.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Thu, 07 May 2009 09:54:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/05/07/269462.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/269462.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/05/07/269462.html#Feedback</comments><slash:comments>20</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/269462.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/269462.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 首先访问qq.mail.com 这个url分析html代码，发现，里面有很多加密的js，而且配合httpwatch工具发现，哇，靠，这个太复杂了。<br />
如果简单的使用java模拟浏览器 访问qq mail服务器获取 好友列表，实在是太困难了，个人能力有限实现不了，想了其他办法，创建了<br />
web项目，分析不了腾讯是怎么加密，但我可以作为一种代理，如图：<br />
<img alt="" src="http://www.blogjava.net/images/blogjava_net/lsbwahaha/p2jpg.JPG" border="0" /><br />
&nbsp;&nbsp; 要采用上面的方式来获取好友，大致可以分为一下几个步骤：<br />
1.首先制作一个login.jsp页面，代码直接从腾讯邮件的登陆页面中复制过来，把页面交互的改成我们自己的服务器.<br />
&nbsp;&nbsp;&nbsp;&nbsp;(1)获取验证码的地址：<a href="http://ptlogin2.qq.com/getimage?aid=23000101">http://ptlogin2.qq.com/getimage?aid=23000101</a> 后面带个随机数，为了防止浏览器缓存。<br />
&nbsp;&nbsp;&nbsp;&nbsp;(2)当用户输入用户名 密码 和验证码，点登陆的时候，也让用户提交到我们的服务器来。<br />
2. 我这里写了一个servlet，该类是从qq邮件服务器中获取验证码的，如何获取呢？我采用的是<br />
httpclient4.0-beta2 包，该包是apache的 Apache HttpComponents project，是个开源的，具体使用和了解可以访问：<br />
<a href="http://hc.apache.org/httpcomponents-client/index.html">http://hc.apache.org/httpcomponents-client/index.html</a>，（该项目功能很强大）<br />
&nbsp;&nbsp;&nbsp; &nbsp; 在获取了验证码之后，qq服务器他在cookie中写了一个verifysession，当你点登陆的时候<br />
客户端校验需要。<br />
3. 把客户端提交过来的信息我们去请求qq服务器，这样就会登陆成功了，服务器会返回带sid的html代码，解析出来sid的值<br />
然后访问http://m11.mail.qq.com/cgi-bin/addr_listall?sid=" +sid+"&amp;sorttype=null&amp;category=common，就获取到qq中好友分组，以及每一个组的链接地址<br />
4.请求每一个链接 &nbsp;就可以得到每一组的好友了 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 上面我只是写了实现的思路，有兴趣的可以跟我联系，具体代码可以分享 给大家 。。。&nbsp; qq：253041869<br />
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/269462.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-05-07 17:54 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/05/07/269462.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>CSVReader的下载地址</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/05/04/268880.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Mon, 04 May 2009 12:04:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/05/04/268880.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/268880.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/05/04/268880.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/268880.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/268880.html</trackback:ping><description><![CDATA[目前最高版本： &nbsp; <a href="http://downloads.sourceforge.net/opencsv/opencsv-1.8-src-with-libs.tar.gz">http://downloads.sourceforge.net/opencsv/opencsv-1.8-src-with-libs.tar.gz</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
&nbsp; 开源的opencsv， 用来操作csv，这个还是不错的。&nbsp;&nbsp; 要看介绍还是去看官方的文档吧，下了，感觉还不错的~&nbsp; 一些使用的东东上面说的很清楚，我也懒的复制了，这个给自己标注下吧。。 hoho
<img src ="http://www.blogjava.net/lsbwahaha/aggbug/268880.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-05-04 20:04 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/05/04/268880.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>servlet中获取（其他网站的）验证码，显示在自己页面上</title><link>http://www.blogjava.net/lsbwahaha/archive/2009/04/23/267226.html</link><dc:creator>胡鹏</dc:creator><author>胡鹏</author><pubDate>Thu, 23 Apr 2009 12:38:00 GMT</pubDate><guid>http://www.blogjava.net/lsbwahaha/archive/2009/04/23/267226.html</guid><wfw:comment>http://www.blogjava.net/lsbwahaha/comments/267226.html</wfw:comment><comments>http://www.blogjava.net/lsbwahaha/archive/2009/04/23/267226.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/lsbwahaha/comments/commentRss/267226.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/lsbwahaha/services/trackbacks/267226.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;有时候要获取其他网站的代码来实现模拟登陆，下面使用servlet来实现：程序代码如下：<br />
<br />
<br />
<div style="border-right: #cccccc 1px solid; padding-right: 5px; border-top: #cccccc 1px solid; padding-left: 4px; font-size: 13px; padding-bottom: 4px; border-left: #cccccc 1px solid; width: 98%; word-break: break-all; padding-top: 4px; border-bottom: #cccccc 1px solid; background-color: #eeeeee"><img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /><span style="color: #000000">String&nbsp;urlStr&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #000000">"</span><span style="color: #000000">http://xxx.xxx.xx.xx</span><span style="color: #000000">"</span><span style="color: #000000">;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URL&nbsp;url&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;</span><span style="color: #0000ff">new</span><span style="color: #000000">&nbsp;URL(urlStr);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;URLConnection&nbsp;conn&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;url.openConnection();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;conn.connect();&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputStream&nbsp;is&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;conn.getInputStream();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">得到输入的编码器，将文件流进行jpg格式编码</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JPEGImageDecoder&nbsp;decoder&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;JPEGCodec.createJPEGDecoder(is);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">得到编码后的图片对象</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;BufferedImage&nbsp;image&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;decoder.decodeAsBufferedImage();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #008000">//</span><span style="color: #008000">得到输出的编码器</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;OutputStream&nbsp;output&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;response.getOutputStream();<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;JPEGImageEncoder&nbsp;encoder&nbsp;</span><span style="color: #000000">=</span><span style="color: #000000">&nbsp;JPEGCodec.createJPEGEncoder(output);<br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;encoder.encode(image);</span><span style="color: #008000">//</span><span style="color: #008000">对图片进行输出编码</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;is.close();</span><span style="color: #008000">//</span><span style="color: #008000">关闭文件流</span><span style="color: #008000"><br />
<img alt="" src="http://www.blogjava.net/images/OutliningIndicators/None.gif" align="top" /></span><span style="color: #000000">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output.close();</span></div>
&nbsp; 比较简单。。。。。hoho
 <img src ="http://www.blogjava.net/lsbwahaha/aggbug/267226.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/lsbwahaha/" target="_blank">胡鹏</a> 2009-04-23 20:38 <a href="http://www.blogjava.net/lsbwahaha/archive/2009/04/23/267226.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>