﻿<?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-风人园-文章分类-算法</title><link>http://www.blogjava.net/wuxufeng8080/category/12855.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 02 Mar 2007 02:04:42 GMT</lastBuildDate><pubDate>Fri, 02 Mar 2007 02:04:42 GMT</pubDate><ttl>60</ttl><item><title>Java加密和数字签名</title><link>http://www.blogjava.net/wuxufeng8080/articles/78466.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Wed, 01 Nov 2006 06:07:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/78466.html</guid><description><![CDATA[
		<a>
				<span class="f14">本文主要谈一下密码学中的加密和数字签名，以及其在java中如何进行使用。对密码学有兴趣的伙伴，推荐看 Bruce Schneier的著作：Applied Crypotography。在jdk1.5的发行版本中安全性方面有了很大的改进，也提供了对RSA算法的直接支持，现在我们从实例入手解决问题（本文仅是作为简单介绍）： <br /><br />　　<strong>一、密码学上常用的概念</strong>　<br /><br />　　1）消息摘要：<br /><br />　　这是一种与消息认证码结合使用以确保消息完整性的技术。主要使用单向散列函数算法，可用于检验消息的完整性，和通过散列密码直接以文本形式保存等，目前广泛使用的算法有MD4、MD5、SHA-1，jdk1.5对上面都提供了支持，在java中进行消息摘要很简单， java.security.MessageDigest提供了一个简易的操作方法：<br /><br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,128,0)">/**</span><span style="COLOR: rgb(0,128,0)"><br />*MessageDigestExample.java<br />*Copyright 2005-2-16<br /></span><span style="COLOR: rgb(0,128,0)">*/</span><span style="COLOR: rgb(0,0,0)"><br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> java.security.MessageDigest;<br /></span><span style="COLOR: rgb(0,128,0)">/**</span><span style="COLOR: rgb(0,128,0)"><br />*单一的消息摘要算法，不使用密码.可以用来对明文消息（如：密码）隐藏保存<br /></span><span style="COLOR: rgb(0,128,0)">*/</span><span style="COLOR: rgb(0,0,0)"><br /></span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)"> MessageDigestExample{<br />　</span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)"> main(String[] args) </span><span style="COLOR: rgb(0,0,255)">throws</span><span style="COLOR: rgb(0,0,0)"> Exception{<br />　　</span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)">(args.length</span><span style="COLOR: rgb(0,0,0)">!=</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">){<br />　　　System.err.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Usage:java MessageDigestExample text</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　　System.exit(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">);<br />　　}<br /><br />　　</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] plainText</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">args[</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">].getBytes(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br /><br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">使用getInstance("算法")来获得消息摘要,这里使用SHA-1的160位算法</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　MessageDigest messageDigest</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">MessageDigest.getInstance(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">SHA-1</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br /><br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">messageDigest.getProvider().getInfo());<br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">开始使用算法</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　messageDigest.update(plainText);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\nDigest:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">输出算法运算结果</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　System.out.println(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> String(messageDigest.digest(),</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br />　}<br />}</span></div><br />　　还可以通过消息认证码来进行加密实现，javax.crypto.Mac提供了一个解决方案，有兴趣者可以参考相关API文档，本文只是简单介绍什么是摘要算法。<br /><br />这里补充另一个运用消息摘要的方式加密的例子:<br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)"> TestEncrypt {<br /><br />    </span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> TestEncrypt() {<br />    }<br /><br />    </span><span style="COLOR: rgb(0,128,0)">/**</span><span style="COLOR: rgb(0,128,0)"><br />     * </span><span style="COLOR: rgb(128,128,128)">@param</span><span style="COLOR: rgb(0,128,0)"> strSrc  :strSrc is a string will be encrypted,<br />     * </span><span style="COLOR: rgb(128,128,128)">@param</span><span style="COLOR: rgb(0,128,0)"> encName : encName is the algorithm name will be used.<br />     *                encName dafault to "MD5"<br />     * </span><span style="COLOR: rgb(128,128,128)">@return</span><span style="COLOR: rgb(0,128,0)"> String<br />     </span><span style="COLOR: rgb(0,128,0)">*/</span><span style="COLOR: rgb(0,0,0)"><br />    </span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> String Encrypt(String strSrc, String encName) {<br /><br />        MessageDigest md </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)">;<br />        String strDes </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)">;<br /><br />        </span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] bt </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> strSrc.getBytes();<br />        </span><span style="COLOR: rgb(0,0,255)">try</span><span style="COLOR: rgb(0,0,0)"> {<br />            </span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)"> (encName </span><span style="COLOR: rgb(0,0,0)">==</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">||</span><span style="COLOR: rgb(0,0,0)"> encName.equals(</span><span style="COLOR: rgb(0,0,0)">""</span><span style="COLOR: rgb(0,0,0)">)) {<br />                encName </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">MD5</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">;<br />            }<br />            md </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> MessageDigest.getInstance(encName);<br />            md.update(bt);<br />            strDes </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> bytes2Hex(md.digest()); </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">to HexString</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">        }<br />        </span><span style="COLOR: rgb(0,0,255)">catch</span><span style="COLOR: rgb(0,0,0)"> (NoSuchAlgorithmException e) {<br />            System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Invalid algorithm.</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />            </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)">;<br />        }<br />        </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> strDes;<br />    }<br /><br />    </span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> String bytes2Hex(</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] bts) {<br />        String des </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">""</span><span style="COLOR: rgb(0,0,0)">;<br />        String tmp </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)">;<br />        </span><span style="COLOR: rgb(0,0,255)">for</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)"> i </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">; i </span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)"> bts.length; i</span><span style="COLOR: rgb(0,0,0)">++</span><span style="COLOR: rgb(0,0,0)">) {<br />            tmp </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> (Integer.toHexString(bts[i] </span><span style="COLOR: rgb(0,0,0)">&amp;</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">0xFF</span><span style="COLOR: rgb(0,0,0)">));<br />            </span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)"> (tmp.length() </span><span style="COLOR: rgb(0,0,0)">==</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">) {<br />                des </span><span style="COLOR: rgb(0,0,0)">+=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">;<br />            }<br />            des </span><span style="COLOR: rgb(0,0,0)">+=</span><span style="COLOR: rgb(0,0,0)"> tmp;<br />        }<br />        </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> des;<br />    }<br /><br />    </span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)"> main(String[]args) {<br />        TestEncrypt te </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> TestEncrypt();<br />        String strSrc </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">可以加密汉字.Oh,and english</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">;<br />        System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Source String:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> strSrc);<br />        System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Encrypted String:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />        System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Use Def:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> te.Encrypt(strSrc, </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)">));<br />        System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Use MD5:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> te.Encrypt(strSrc, </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">MD5</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br />        System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Use SHA:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> te.Encrypt(strSrc, </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">SHA-1</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br />        System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Use SHA-256:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> te.Encrypt(strSrc, </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">SHA-256</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br />    }<br />}</span></div><br />另外，在javawebparts中的 RequestHelpers里的generateGUID方法也涉及到了MD5的方法，代码如下:<br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)"> String generateGUID(HttpServletRequest request) {<br /><br />    String out </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">""</span><span style="COLOR: rgb(0,0,0)">;<br />    </span><span style="COLOR: rgb(0,0,255)">try</span><span style="COLOR: rgb(0,0,0)"> {<br />      </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> Construct a string that is comprised of:<br />      </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> Remote IP Address + Host IP Address + Date (yyyyMMdd) +<br />      </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> Time (hhmmssSSa) + Requested Path + Session ID +<br />      </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> HashCode Of ParameterMap</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">      StringBuffer sb </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> StringBuffer(</span><span style="COLOR: rgb(0,0,0)">1024</span><span style="COLOR: rgb(0,0,0)">);<br />      sb.append(request.getRemoteAddr());<br />      InetAddress ia </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> InetAddress.getLocalHost();<br />      sb.append(ia.getHostAddress());<br />      sb.append(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> SimpleDateFormat(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">yyyyMMddhhmmssSSa</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">).format(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> Date()));<br />      String path </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> request.getServletPath();<br />      String pathInfo </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> request.getPathInfo();<br />      </span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)"> (pathInfo </span><span style="COLOR: rgb(0,0,0)">!=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">null</span><span style="COLOR: rgb(0,0,0)">) {<br />        path </span><span style="COLOR: rgb(0,0,0)">+=</span><span style="COLOR: rgb(0,0,0)"> pathInfo;<br />      }<br />      sb.append(path);<br />      sb.append(request.getSession(</span><span style="COLOR: rgb(0,0,255)">false</span><span style="COLOR: rgb(0,0,0)">));<br />      sb.append(request.getParameterMap().hashCode());<br />      String str </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> sb.toString();<br />      </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> Now encode the string using an MD5 encryption algorithm.</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">      MessageDigest md </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> MessageDigest.getInstance(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">md5</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />      md.update(str.getBytes());<br />      </span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] digest </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> md.digest();<br />      StringBuffer hexStr </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> StringBuffer(</span><span style="COLOR: rgb(0,0,0)">1024</span><span style="COLOR: rgb(0,0,0)">);<br />      </span><span style="COLOR: rgb(0,0,255)">for</span><span style="COLOR: rgb(0,0,0)"> (</span><span style="COLOR: rgb(0,0,255)">int</span><span style="COLOR: rgb(0,0,0)"> i </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">; i </span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)"> digest.length; i</span><span style="COLOR: rgb(0,0,0)">++</span><span style="COLOR: rgb(0,0,0)">) {<br />        str </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> Integer.toHexString(</span><span style="COLOR: rgb(0,0,0)">0xFF</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">&amp;</span><span style="COLOR: rgb(0,0,0)"> digest[i]);<br />        </span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)"> (str.length() </span><span style="COLOR: rgb(0,0,0)">&lt;</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">2</span><span style="COLOR: rgb(0,0,0)">) {<br />          str </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)"> str;<br />        }<br />        hexStr.append(str);<br />      }<br />      out </span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)"> hexStr.toString();<br />    } </span><span style="COLOR: rgb(0,0,255)">catch</span><span style="COLOR: rgb(0,0,0)"> (NoSuchAlgorithmException nsae) {<br />      log.error(nsae);<br />    } </span><span style="COLOR: rgb(0,0,255)">catch</span><span style="COLOR: rgb(0,0,0)"> (UnknownHostException uhe) {<br />      log.error(uhe);<br />    }<br />    </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> Return the encrypted string.  It should be unique based on the<br />    </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> components that comprise the plain text string, and should always be<br />    </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> 32 characters thanks to the MD5 algorithm.</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">    </span><span style="COLOR: rgb(0,0,255)">return</span><span style="COLOR: rgb(0,0,0)"> out;<br /><br />  } </span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)"> End generateGUID().</span></div><br /><br />　　2）私钥加密：<br /><br />　　消息摘要只能检查消息的完整性，但是单向的，对明文消息并不能加密，要加密明文的消息的话，就要使用其他的算法，要确保机密性，我们需要使用私钥密码术来交换私有消息。<br /><br />　　这种最好理解，使用对称算法。比如：A用一个密钥对一个文件加密，而B读取这个文件的话，则需要和A一样的密钥，双方共享一个私钥（而在web环境下，私钥在传递时容易被侦听）：<br /><br />　　使用私钥加密的话，首先需要一个密钥，可用javax.crypto.KeyGenerator产生一个密钥(java.security.Key), 然后传递给一个加密工具(javax.crypto.Cipher),该工具再使用相应的算法来进行加密，主要对称算法有：DES（实际密钥只用到56 位），AES（支持三种密钥长度：128、192、256位），通常首先128位，其他的还有DESede等，jdk1.5种也提供了对对称算法的支持，以下例子使用AES算法来加密：<br /><br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,128,0)">/**</span><span style="COLOR: rgb(0,128,0)"><br />*PrivateExmaple.java<br />*Copyright 2005-2-16<br /></span><span style="COLOR: rgb(0,128,0)">*/</span><span style="COLOR: rgb(0,0,0)"><br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> javax.crypto.Cipher;<br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> javax.crypto.KeyGenerator;<br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> java.security.Key;<br /><br /></span><span style="COLOR: rgb(0,128,0)">/**</span><span style="COLOR: rgb(0,128,0)"><br />*私鈅加密，保证消息机密性<br /></span><span style="COLOR: rgb(0,128,0)">*/</span><span style="COLOR: rgb(0,0,0)"><br /></span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)"> PrivateExample{<br />　</span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)"> main(String[] args) </span><span style="COLOR: rgb(0,0,255)">throws</span><span style="COLOR: rgb(0,0,0)"> Exception{<br />　　</span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)">(args.length</span><span style="COLOR: rgb(0,0,0)">!=</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">){<br />　　　System.err.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Usage:java PrivateExample &lt;text&gt;</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　　System.exit(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">);<br />　　}<br />　　</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] plainText</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">args[</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">].getBytes(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br /><br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">通过KeyGenerator形成一个key</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\nStart generate AES key</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　KeyGenerator keyGen</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">KeyGenerator.getInstance(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">AES</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　keyGen.init(</span><span style="COLOR: rgb(0,0,0)">128</span><span style="COLOR: rgb(0,0,0)">);<br />　　Key key</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">keyGen.generateKey();<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Finish generating DES key</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br /><br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">获得一个私鈅加密类Cipher，ECB是加密方式，PKCS5Padding是填充方法</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　Cipher cipher</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">Cipher.getInstance(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">AES/ECB/PKCS5Padding</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">cipher.getProvider().getInfo());<br /><br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">使用私鈅加密</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\nStart encryption:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　cipher.init(Cipher.ENCRYPT_MODE,key);<br />　　</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] cipherText</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">cipher.doFinal(plainText);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Finish encryption:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> String(cipherText,</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br /><br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\nStart decryption:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　cipher.init(Cipher.DECRYPT_MODE,key);<br />　　</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] newPlainText</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">cipher.doFinal(cipherText);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Finish decryption:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br /><br />　　System.out.println(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> String(newPlainText,</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br /><br />　}<br />}</span></div><br />　　3）公钥加密：<br /><br />　　上面提到，私钥加密需要一个共享的密钥，那么如何传递密钥呢？web环境下，直接传递的话很容易被侦听到，幸好有了公钥加密的出现。公钥加密也叫不对称加密，不对称算法使用一对密钥对，一个公钥，一个私钥，使用公钥加密的数据，只有私钥能解开（可用于加密）；同时，使用私钥加密的数据，只有公钥能解开（签名）。但是速度很慢（比私钥加密慢100到1000倍），公钥的主要算法有RSA，还包括Blowfish,Diffie-Helman等， jdk1.5种提供了对RSA的支持，是一个改进的地方： <br /><br /><div style="BORDER-RIGHT: rgb(204,204,204) 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: rgb(204,204,204) 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: rgb(204,204,204) 1px solid; WIDTH: 98%; PADDING-TOP: 4px; BORDER-BOTTOM: rgb(204,204,204) 1px solid; BACKGROUND-COLOR: rgb(238,238,238)"><!--<br><br>Code highlighting produced by Actipro CodeHighlighter (freeware)<br>http://www.CodeHighlighter.com/<br><br>--><span style="COLOR: rgb(0,128,0)">/**</span><span style="COLOR: rgb(0,128,0)"><br />*PublicExample.java<br />*Copyright 2005-2-16<br /></span><span style="COLOR: rgb(0,128,0)">*/</span><span style="COLOR: rgb(0,0,0)"><br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> java.security.Key;<br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> javax.crypto.Cipher;<br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> java.security.KeyPairGenerator;<br /></span><span style="COLOR: rgb(0,0,255)">import</span><span style="COLOR: rgb(0,0,0)"> java.security.KeyPair;<br /></span><span style="COLOR: rgb(0,128,0)">/**</span><span style="COLOR: rgb(0,128,0)"><br />*一个简单的公鈅加密例子,Cipher类使用KeyPairGenerator生成的公鈅和私鈅<br /></span><span style="COLOR: rgb(0,128,0)">*/</span><span style="COLOR: rgb(0,0,0)"><br /></span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">class</span><span style="COLOR: rgb(0,0,0)"> PublicExample{<br />　</span><span style="COLOR: rgb(0,0,255)">public</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">static</span><span style="COLOR: rgb(0,0,0)"> </span><span style="COLOR: rgb(0,0,255)">void</span><span style="COLOR: rgb(0,0,0)"> main(String[] args) </span><span style="COLOR: rgb(0,0,255)">throws</span><span style="COLOR: rgb(0,0,0)"> Exception{<br />　　</span><span style="COLOR: rgb(0,0,255)">if</span><span style="COLOR: rgb(0,0,0)">(args.length</span><span style="COLOR: rgb(0,0,0)">!=</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">){<br />　　　System.err.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Usage:java PublicExample &lt;text&gt;</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　　System.exit(</span><span style="COLOR: rgb(0,0,0)">1</span><span style="COLOR: rgb(0,0,0)">);<br />　　}<br /><br />　　</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] plainText</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">args[</span><span style="COLOR: rgb(0,0,0)">0</span><span style="COLOR: rgb(0,0,0)">].getBytes(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">构成一个RSA密钥</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\nStart generating RSA key</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　KeyPairGenerator keyGen</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">KeyPairGenerator.getInstance(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">RSA</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　keyGen.initialize(</span><span style="COLOR: rgb(0,0,0)">1024</span><span style="COLOR: rgb(0,0,0)">);<br />　　KeyPair key</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">keyGen.generateKeyPair();<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Finish generating RSA key</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br /><br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">获得一个RSA的Cipher类，使用公鈅加密</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　Cipher cipher</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">Cipher.getInstance(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">RSA/ECB/PKCS1Padding</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\n</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">+</span><span style="COLOR: rgb(0,0,0)">cipher.getProvider().getInfo());<br /><br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\nStart encryption</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　cipher.init(Cipher.ENCRYPT_MODE,key.getPublic());<br />　　</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] cipherText</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">cipher.doFinal(plainText);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Finish encryption:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> String(cipherText,</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br /><br />　　</span><span style="COLOR: rgb(0,128,0)">//</span><span style="COLOR: rgb(0,128,0)">使用私鈅解密</span><span style="COLOR: rgb(0,128,0)"><br /></span><span style="COLOR: rgb(0,0,0)">　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">\nStart decryption</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　cipher.init(Cipher.DECRYPT_MODE,key.getPrivate());<br />　　</span><span style="COLOR: rgb(0,0,255)">byte</span><span style="COLOR: rgb(0,0,0)">[] newPlainText</span><span style="COLOR: rgb(0,0,0)">=</span><span style="COLOR: rgb(0,0,0)">cipher.doFinal(cipherText);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">Finish decryption:</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">);<br />　　System.out.println(</span><span style="COLOR: rgb(0,0,255)">new</span><span style="COLOR: rgb(0,0,0)"> String(newPlainText,</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">UTF8</span><span style="COLOR: rgb(0,0,0)">"</span><span style="COLOR: rgb(0,0,0)">));<br />　}<br />}</span></div></span>
		</a>
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/78466.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-11-01 14:07 <a href="http://www.blogjava.net/wuxufeng8080/articles/78466.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>BMP、GIF和JPEG文件格式简介</title><link>http://www.blogjava.net/wuxufeng8080/articles/57060.html</link><dc:creator>风人园</dc:creator><author>风人园</author><pubDate>Fri, 07 Jul 2006 00:10:00 GMT</pubDate><guid>http://www.blogjava.net/wuxufeng8080/articles/57060.html</guid><description><![CDATA[
		<div class="postcontent">
				<span class="line">　　图象文件就是描绘了一幅图象的计算机磁盘文件。形成数字图象数据后，将其存储在计算机里的方法有2种，即位映射和向量处理方式。<br />　　我们这里主要讨论的是位图。不同图象软件几乎都用各种的方法处理图象，图象格式也多种多样，它主要包括文件识别头和图象数据。文件识别头用来让计算机判断是哪种文件格式，图象数据包含了整个对图象描绘相关数据，包括调色板、位图映象等。根据压缩算法不同，映象方式也不同，下面简要介绍一下压缩算法。 </span>
				<p>
						<span class="line">
								<b>
										<font color="#5288c7">一、 行程长度压缩</font>
								</b>
								<br />　　原理是将一扫描行中的颜色值相同的相邻像素用一个计数值和那些像素的颜色值来代替。例如:aaabccccccddeee，则可用3a1b6c2d3e来代替。对于拥有大面积，相同颜色区域的图像，用RLE压缩方法非常有效。由RLE原理派生出许多具体行程压缩方法: <br />　　1.PCX行程压缩方法: 该算法实际上是位映射格式到压缩格式的转换算法，该算法对于连续出现1次的字节Ch，若Ch&gt;0xc0则压缩时在该字节前加上0xc1，否则直接输出Ch，对于连续出现N 次的字节Ch，则压缩成0xc0＋N，Ch这两个字节，因而N最大只能为ff－c0=3fh(十进制为63)，当N大于63时， 则需分多次压缩。 <br />　　2.BI_RLE8压缩方法:在WINDOWS的位图文件中采用了这种压缩方法。该压缩方法编码也是以两个字节为基本单位。其中第一个字节规定了用第二个字节指定的颜色重复次数。 如编码 0504表示从当前位置开始连续显示5个颜色值为04的像素。当第二个字节为零时第二个字节有特殊含义:0表示行末;1表示图末;2转义后面2个字节， 这两个字节分别表示下一像素相对于当前位置的水平位移和垂直位移。这种压缩方法所能压缩的图像像素位数最大为8位(256色)图像。<br />　　3.BI_RLE压缩方法: 该方法也用于WINDOWS位图文件中，它与 BI_RLE8编码类似，唯一不同是:BI_RLE4的一个字节包含了两个像素的颜色，因此，它只能压缩的颜色数不超过16的图像。因而这种压缩应用范围有限。 <br />　　4.紧缩位压缩方法(Packbits):该方法是用于Apple公司的Macintosh机上的位图数据压缩 方法， TIFF 规范中使用了这种方法， 这种压缩方法与BI_RLE8压缩方法相似，如1c1c1c2132325648 压缩为:83 1c 21 81 32 56 48，显而易见， 这种压缩方法最好情况是每连续128个字节相同，这128个字节可压缩为一个数值7f。这种方法还是非常有效的。 </span>
				</p>
				<p>
						<span class="line">
								<b>
										<font color="#5288c7">二、霍夫曼编码压缩:</font>
								</b>
								<br />　　也是一种常用的压缩方法。是1952年为文本文件建立的，其基本原理是频繁使用的数据用较短的代码代替，很少使用的数据用较长的代码代替，每个数据的代码各不相同。这些代码都是二进制码，且码的长度是可变的。如: 有一个原始数据序列，ABACCDAA则编码为A(0)，B(10)，C(110),(D111)，压缩后为010011011011100。产生霍夫曼编码需要对原始数据扫描两遍，第一遍扫描要精确地统计出原始数据中的每个值出现的频率，第二遍是建立霍夫曼树并进行编码，由于需要建立二叉树并遍历二叉树生成编码，因此数据压缩和还原速度都较慢，但简单有效，因而得到广泛的应用。</span>
				</p>
				<p>
						<span class="line">
								<b>
										<font color="#5288c7">三、LZW压缩方法</font>
								</b>
								<br />　　LZW压缩技术比其它大多数压缩技术都复杂， 压缩效率也较高。其基本原理是把每一个第一次出现的字符串用一个数值来编码，在还原程序中再将这个数值还成原来的字符 串，如用数值0x100代替字符串"abccddeee"这样每当出现该字符串时，都用0x100代替，起到了压缩的作用。 至于0x100与字符串的对应关系则是在压缩过程中动态生成的，而且这种对应关系是隐含在压缩数据中，随着解压缩的进行这张编码表会从压缩数据中逐步得到恢复，后面的压缩数据再根据前面数据产生的对应关系产生更多的对应关系。直到压缩文件结束为止。LZW是可逆的， 所有信息全部保留。</span>
				</p>
				<p>
						<span class="line">
								<b>
										<font color="#5288c7">四、算术压缩方法</font>
								</b>
								<br />　　算术压缩与霍夫曼编码压缩方法类似，只不过它比霍夫曼编码更加有效。算术压缩适合于由相同的重复序列组成的文件，算术压缩接近压缩的理论极限。这种方法，是将不同的序列映像到0到1之间的区域内，该区域表示成可变精度(位数 )的二进制小数，越不常见的数据要的精度越高(更多的位数)，这种方法比较复杂，因而不太常用。</span>
				</p>
				<p>
						<span class="line">
								<b>
										<font color="#5288c7">五、 JPEG( 联合摄影专家组 Joint Photographic Exprerts Group)</font>
								</b>
								<br />　　JPEG标准与其它的标准不同，它定义了不兼容的编码方法，在它最常用的模式中，它是带失真的，一个从JPEG文件恢复出来的图像与原始图像总是不同的，但有损压缩重建后的图像常常比原始图像的效果更好。JPEG的另一个显著的特点是它的压缩比例相当高，原图像大小与压缩后的图像大小相比，比例可以从1％到80～90％不等。 这种方法效 果也好，适合多媒体系统。</span>
				</p>
				<p>
						<span class="line">　　介绍完了压缩算法，我们来简要介绍一下三种位图格式的异同和它们之间的相互转换。<br />　　<b>1. bmp图象</b><br />　　　· 位图文件头(BITMAPHEADER)数据结构<br />　　　· 位图信息(BITMAPINFO)数据结构<br />　　　· 位图阵列</span>
				</p>
				<p>
						<span class="line">　　1)位图文件头数据结构包含BMP图象文件的类型、显示内容等信息。<br />　　Typedef struct{<br />　　　　　　Int bfType; //must be "BM"<br />　　　　　　Long bfSize; //位图大小<br />　　　　　　Int bfReserved1;//must be "0"<br />　　　　　　Int bfReserved2;//must be "0"<br />　　　　　　Long bfOffBits;//位图阵列的起始位置<br />　　}BITMAPEFILEHEADER;</span>
				</p>
				<p>
						<span class="line">　　2)位图信息数据结构由BITMAPINFOHEADER和RGBQUAD两个数据结构组成，<br />　　typedef struct{<br />　　　　　　BITMAPINFOHEADER bmiHeader;<br />　　　　　　RGBQUAD bmiColors[];<br />　　}BITMAPINFO</span>
				</p>
				<p>
						<span class="line">　　其中BITMAPINFOHEADER数据结构包含了有关BMP图象的宽、高、压缩方法等信息。<br />　　数据结构RGBQUAD定义一种颜色。</span>
				</p>
				<p>
						<span class="line">　　3）位图阵列<br />　　位图阵列记录了图象的每一个象素值。从图象的左下角开始逐行扫描图象。从左到右，从上到下，将图象的象素值逐一记录下来，这些记录象素值的字节组成了位图阵列。<br />　　位图阵列数据的存储格式有压缩和非压缩两种格式。<br />　　1． 非压缩格式 位图中的每一个点的象素值对应与位图阵列的若干位，而位图阵列的若干位由图象的高度、宽度及图象的颜色数决定。<br />　　2． 压缩格式 在bmp格式文件中，Windows支持BI-RLE8和BI-RLE4两种压缩类型的存储格式。</span>
				</p>
				<p>
						<span class="line">　　<b>2、GIF图象文件格式</b><br />　　GIF的全称是Graphics Interchange Format,.译做图形交换格式。GIF是一种公用的图象文件格式标准，但它归compuServe公司版权所有。<br />GIF文件结构包含一个文件头，</span>
						<span class="line">在一个GIF文件中首先碰到的是GIF的标志，这个标志告诉解码程序这是个GIF文件。这个标志是3字节的串：GIF。一个GIF文件中可以存放多幅图象，但绝大多数的文件都只包含一幅图象。<br />　　然后是屏幕描述字(screen descriptor),说明了用来生成的显示文件中的图象的显示器分辨率，分别表示屏幕的宽和高。<br />　　紧跟下来的一个字节是全局标志，其低三位说明了即将碰到的图象是多少颜色的。最高位表示是否存在一个全局色彩表。<br />　　背景色表示把背景置成适当的颜色，实际上是一个指向全局色彩表的数。<br />　　Struct Global_Data{<br />　　　　Unsigned short screen_width;<br />　　　　Unsigned short screen_height;<br />　　　　Unsigned char background;<br />　　　　har tail='\0';<br />　　　　}<br />　　接下来是全局色彩表，按顺序存放所有的严肃，每一种严肃由色彩表的一项来描述，每项是3字节，分别表示红、绿、蓝三种原色的强度。其长度有全局标志的低三位表示。<br />　　以后的数据都是局部的了。是些数据块的集合。下面是图象数据块的结构。<br />　　Struct Local_Head{<br />　　　　　　Char heading=',';<br />　　　　　　Unsigned short image_left;//图象的屏幕上显示的起始位置<br />　　　　Unsigned short image_top;<br />　　　　Unsigned short image_width;<br />　　　　Unsigned short image-height;<br />　　　　Unsigned char local_flag;//局部标志<br />　　　　} </span>
				</p>
				<p>
						<span class="line">　　局部标志和 全局标志的不同之处在于次高位，如果这位被置成1则表示图像的位图数据是以隔行方式存放的。也就是说，在解开的位图数据中，第一行存放的是屏幕上第一行，第二行对应屏幕上的第9行，第三行对应屏幕上的第17行，以此递增--这是第一遍扫描；第二遍扫描是从屏幕上的第5行开始，两行之间也是以8递增；第三遍扫描是从屏幕上的第3行开始，两行之间以4递增；第四遍扫描，也是最后一遍，从第2行开始，两行之间以2递增。</span>
						<span class="line">隔行存放的GIF图像在边解码边显示的时候可分成四遍扫描。第一遍扫描虽然只显示了整个图像的八分之一，第二遍的扫描后也只显示了四分之一，但这已经把整个图像的概貌显示出来了。在显示GIF图像的时，隔行存放的图像会给你这样一个印象：向它的显示速度似乎要比其他图像快一些，这是隔行存放的优点。<br />　　在GIF图像的编解码中用到了LZW压缩算法--把这些字符流转换成另一种形式的代码流，解码过程则是把这种代码流还原成原来的字符流。</span>
				</p>
				<p>
						<span class="line">　　<b>3、JPEG图象文件格式</b><br />　　JPEG是Joint Photographic Experts Group(联合摄影专家小组)的首字母缩写。JPEG的主要作用是用于数字化图象的标准编码技术。JPEG图象文件是一种象素格式文件格式，但它比诸如象GIF、BMP等图象文件要复杂的多。所幸,我们在使用由JPEG组成的JPEG库时,只要对该文件格式有个一般的了解就可以了。而没有必要对JPEG文件格式做一个全面细致的了解。<br />　　JPEG格式是种有损的编码格式，但如果GIF文件比，他经过解码后的重构图象要比GIF图象更接近于原始的图象。 JPEG编码技术是由颜色转换、DCT变换、进行量化、编码。其压缩格式由著名的JPEG集团所著的4.0版本的库所定。</span>
				</p>
				<p>
						<span class="line">　　关于这3种图象格式的互相转换，主要是用c语言或c++和汇编语言，因为这些语言可以 直接进行底层的操作，把图象解压缩后按用另一种格式要求进行压缩即可。<br />本文属转载，原文地址：<a href="http://www.chinaaspx.com/comm/dotnetbbs/Showtopic.aspx?Forum_ID=44&amp;Id=139926&amp;PPage=1">http://www.chinaaspx.com/comm/dotnetbbs/Showtopic.aspx?Forum_ID=44&amp;Id=139926&amp;PPage=1</a></span>
				</p>
		</div>
<img src ="http://www.blogjava.net/wuxufeng8080/aggbug/57060.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuxufeng8080/" target="_blank">风人园</a> 2006-07-07 08:10 <a href="http://www.blogjava.net/wuxufeng8080/articles/57060.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>