<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    bt下載與小說520

    bt下載與小說520

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      16 隨筆 :: 0 文章 :: 6 評(píng)論 :: 0 Trackbacks

    2008年10月7日 #

    Mozilla Public License

    MPL License,允許免費(fèi)重發(fā)布、免費(fèi)修改,但要求修改后的代碼版權(quán)歸軟件的發(fā)起者。這種授權(quán)維護(hù)了商業(yè)軟件的利益,,它要求基于這種軟件得修改無償貢獻(xiàn)版權(quán)給該軟件。這樣,圍繞該軟件得所有代碼得版權(quán)都集中在發(fā)起開發(fā)人得手中。但MPL是允許修改,無償使用得。MPL軟件對(duì)鏈接沒有要求。

    SD開源協(xié)議

    BSD開源協(xié)議是一個(gè)給于使用者很大自由的協(xié)議。可以自由的使用,修改源代碼,也可以將修改后的代碼作為開源或者專有軟件再發(fā)布。 當(dāng)你發(fā)布使用了BSD協(xié)議的代碼,或則以BSD協(xié)議代碼為基礎(chǔ)做二次開發(fā)自己的產(chǎn)品時(shí),需要滿足三個(gè)條件:

    1. 如果再發(fā)布的產(chǎn)品中包含源代碼,則在源代碼中必須帶有原來代碼中的BSD協(xié)議。

    2. 如果再發(fā)布的只是二進(jìn)制類庫/軟件,則需要在類庫/軟件的文檔和版權(quán)聲明中包含原來代碼中的BSD協(xié)議。

    3. 不可以用開源代碼的作者/機(jī)構(gòu)名字和原來產(chǎn)品的名字做市場(chǎng)推廣。

    BSD代碼鼓勵(lì)代碼共享,但需要尊重代碼作者的著作權(quán)。BSD由于允許使用者修改和重新發(fā)布代碼,也允許使用或在BSD代碼上開發(fā)商業(yè)軟件發(fā)布和銷售,因此是對(duì)商業(yè)集成很友好的協(xié)議。而很多的公司企業(yè)在選用開源產(chǎn)品的時(shí)候都首選BSD協(xié)議,因?yàn)榭梢酝耆刂七@些第三方的代碼,在必要的時(shí)候可以修改或者二次開發(fā)。

    Apache Licence 2.0

    Apache Licence是著名的非盈利開源組織Apache采用的協(xié)議。該協(xié)議和BSD類似,同樣鼓勵(lì)代碼共享和尊重原作者的著作權(quán),同樣允許代碼修改,再發(fā)布(作為開源或商業(yè)軟件)。需要滿足的條件:

    1. 需要給代碼的用戶一份Apache Licence

    2. 如果你修改了代碼,需要再被修改的文件中說明。

    3. 在延伸的代碼中(修改和有源代碼衍生的代碼中)需要帶有原來代碼中的協(xié)議,商標(biāo),專利聲明和其他原來作者規(guī)定需要包含的說明。

    4. 如果再發(fā)布的產(chǎn)品中包含一個(gè)Notice文件,則在Notice文件中需要帶有Apache Licence。你可以在Notice中增加自己的許可,但不可以表現(xiàn)為對(duì)Apache Licence構(gòu)成更改。

    Apache Licence也是對(duì)商業(yè)應(yīng)用友好的許可。使用者也可以在需要的時(shí)候修改代碼來滿足需要并作為開源或商業(yè)產(chǎn)品發(fā)布/銷售。

    GPL

    GPL許可證是自由軟件的應(yīng)用最廣泛的軟件許可證,人們可以修改程式的一個(gè)或幾個(gè)副本或程式的任何部分,以此形成基於這些程式的衍生作品。必須在修改過的檔案中附有明顯的說明:您修改了此一檔案及任何修改的日期。 您必須讓您發(fā)布或出版的作品,包括本程式的全部或一部分,或內(nèi)含本程式的全部或部分所衍生的作品,允許第三方在此許可證條款下使用,并且不得因?yàn)榇隧?xiàng)授權(quán)行為而收費(fèi)。

    LGPL

    Linux就是采用了GPL。GPL協(xié)議和BSD, Apache Licence等鼓勵(lì)代碼重用的許可很不一樣。GPL的出發(fā)點(diǎn)是代碼的開源/免費(fèi)使用和引用/修改/衍生代碼的開源/免費(fèi)使用,但不允許修改后和衍生的代碼做為閉源的商業(yè)軟件發(fā)布和銷售。這也就是為什么我們能用免費(fèi)的各種linux,包括商業(yè)公司的linux和linux上各種各樣的由個(gè)人,組織,以及商業(yè)軟件公司開發(fā)的免費(fèi)軟件了。

    GPL協(xié)議的主要內(nèi)容是只要在一個(gè)軟件中使用(“使用”指類庫引用,修改后的代碼或者衍生代碼)GPL協(xié)議的產(chǎn)品,則該軟件產(chǎn)品必須也采用GPL協(xié)議,既必須也是開源和免費(fèi)。這就是所謂的”傳染性”。GPL協(xié)議的產(chǎn)品作為一個(gè)單獨(dú)的產(chǎn)品使用沒有任何問題,還可以享受免費(fèi)的優(yōu)勢(shì)。

    由于GPL嚴(yán)格要求使用了GPL類庫的軟件產(chǎn)品必須使用GPL協(xié)議,對(duì)于使用GPL協(xié)議的開源代碼,商業(yè)軟件或者對(duì)代碼有保密要求的部門就不適合集成/采用作為類庫和二次開發(fā)的基礎(chǔ)。

    其它細(xì)節(jié)如再發(fā)布的時(shí)候需要伴隨GPL協(xié)議等和BSD/Apache等類似。

    Public Domain

    公共域授權(quán)。將軟件授權(quán)為公共域,這些軟件包沒有授權(quán)協(xié)議,任何人都可以隨意使用它。

    Artistic許可

    使作者保持對(duì)進(jìn)一步開發(fā)的控制。

    posted @ 2008-12-18 13:55 bt下載| 編輯 收藏

    著第3屆bt論壇的順利結(jié)束的秋風(fēng),我也來分享一下自己在前端優(yōu)化方面的一些些小經(jīng)驗(yàn),其實(shí)這些經(jīng)驗(yàn)本身都是來自yahoo的優(yōu)化原則,不過經(jīng)過ahuaxuan自身的實(shí)踐和再次的思考,把原來的原則都進(jìn)行了分組和分析.不過由于ahuaxuan bt涉及到的東西有限,并沒有經(jīng)歷過全部的優(yōu)化點(diǎn),所以只把自己做過的拿出來和大家討論討論,其中不免加入自己一些觀點(diǎn),希望大家指正.

    先說說目標(biāo),前端優(yōu)化的目標(biāo)是什么,一個(gè)字:快.兩個(gè)字:更快.那么下面我們來看看慢的網(wǎng)頁將會(huì)給我們帶來什么:
    1. 慢的頁面可能會(huì)網(wǎng)站失去更多的用戶.

    2. 慢500ms意味著20%的用戶將放棄訪問(google)

    3. 慢100ms意味著1%的用戶將放棄交易(amazon)

    4. 慢 ???ms意味著??%的用戶將放棄xx(your site)

    所以我們的目標(biāo)很明確,就是要網(wǎng)頁展現(xiàn)的速度更快.
    經(jīng)過ahuaxuan的實(shí)踐和總結(jié),其實(shí)要讓網(wǎng)頁展現(xiàn)更快只需要注意幾個(gè)大的方面,下面會(huì)一一描述這幾個(gè)大的方面.


    [size=medium]1減少http請(qǐng)求,我把它排在了第一點(diǎn),為啥要在第一點(diǎn)呢,很簡(jiǎn)單,因?yàn)樗钪匾?



    如何做呢.讓ahuaxuan帶著大家分析一下這個(gè)問題.從何處著手呢.ahuaxuan大聲疾呼,我們要從數(shù)據(jù)開始.ok,一般來說,我們從變化性上把數(shù)據(jù)分成兩種類型,變和不變.那么不變的數(shù)據(jù)可以緩存,變化的數(shù)據(jù)不能緩存,這是一個(gè)常識(shí),也就是說要減少我們的http請(qǐng)求次數(shù)這個(gè)目標(biāo)可以轉(zhuǎn)換成把數(shù)據(jù)分為變化和不變化兩個(gè)部分.不變化的數(shù)據(jù)不需要再次請(qǐng)求,這樣http請(qǐng)求的次數(shù)就減少了,下面我們分點(diǎn)來描述將數(shù)據(jù)分類的途徑.


    1. 合并腳本文件
    包括腳本,樣式和圖片,可以有選擇的把一些Js和css可以合并成一個(gè)文件,一些圖片可以使用css sprites技術(shù).這樣做的原因是什么?做過web開發(fā)的人都知道,js和css基本是不變的,是靜態(tài)文件,圖片亦然.那么不變的文件如果適當(dāng)?shù)暮喜⒃谝黄?會(huì)有什么效果呢?請(qǐng)求的次數(shù)從多次變成了一次.這樣http請(qǐng)求的次數(shù)就減少了.當(dāng)時(shí)合并之后,文件體積變大了,會(huì)影響速度嗎?答:肯定會(huì)啊,不過這里是需要權(quán)衡的,比如我100份靜態(tài)文件,合并成10份還是合并成1份這就得看你得具體情況了.

    2. 指定Expires或者Cache-Control,
    對(duì)于靜態(tài)內(nèi)容:設(shè)置文件頭過期時(shí)間Expires的值為“Never expire”(永不過期)
    動(dòng)態(tài)頁面,在代碼中添加cache-control,表示多少時(shí)間之后過期,如:
    response.setHeader("Cache-Control", "max-age=3600");
    如果使用了Expires文件頭,當(dāng)頁面內(nèi)容改變時(shí)就必須改變內(nèi)容的文件名。通常是在文件內(nèi)容后加版本號(hào)
    這一點(diǎn)是大多數(shù)人都忽略得,之前很多人在壇子上發(fā)布自己得小系統(tǒng),還有demo,ahuaxuan跑過去一看,my god,一堆又一堆得js,css,既沒有恰當(dāng)?shù)煤喜?也沒有設(shè)置過期時(shí)間.每次刷新頁面都要重新下載這一堆又一堆的js,css.http請(qǐng)求那叫一個(gè)多啊.無謂了流量就這樣產(chǎn)生了.

    這一點(diǎn)在企業(yè)應(yīng)用的系統(tǒng)中也時(shí)有發(fā)生.比如我們使用extjs作為前端的技術(shù),400多k啊,每打開一個(gè)頁面都導(dǎo)入,下載這個(gè)js,夠無聊的.那么童子們可能就要問了,靜態(tài)文件為啥不用apache,lighttpd等呢,答,用了又怎么樣,不設(shè)expire或者max-age不是一樣要下載,最好的方法是寫一個(gè)filter,再filter中判斷,如果url滿足一定的條件(比如符合配置文件中的正則表達(dá)式),那么就設(shè)置一個(gè)max-age,這樣就ok,太簡(jiǎn)單了,幾行代碼就可以搞定.快哉.

    3. 緩存Ajax請(qǐng)求
    緩存的方法同動(dòng)態(tài)頁面,ajax請(qǐng)求需要使用get方式,url長(zhǎng)度為2k(ie)限制(post請(qǐng)求有兩個(gè)過程,1發(fā)送請(qǐng)求headers,2發(fā)送請(qǐng)求數(shù)據(jù),根據(jù)http規(guī)范,get請(qǐng)求只會(huì)發(fā)送一個(gè)tcp包).--------這一段話來自yahoo,先不管其真假,我們從另外一個(gè)方面來考慮一下為什么最好使用get方式,講一個(gè)ahuaxuan經(jīng)歷過的事情,之前有一個(gè)項(xiàng)目的ajax請(qǐng)求使用了post方式,后來發(fā)現(xiàn)經(jīng)常出錯(cuò),而且拋出了squid的錯(cuò)誤,因?yàn)槲覀兊木W(wǎng)站使用了squid,問題就出在這里了,從http協(xié)議上可以了解到,method=post是指把數(shù)據(jù)提交到服務(wù)器上去,那么squid的一個(gè)特性是不會(huì)緩存post請(qǐng)求(事實(shí)上它確實(shí)不應(yīng)該緩存,因?yàn)檫@樣會(huì)違反http協(xié)議中的語義),把a(bǔ)jax請(qǐng)求改成get方式之后,一切恢復(fù)如常.

    4. 移除重復(fù)的js
    重復(fù)的js導(dǎo)入也有可能導(dǎo)致ie重新加載該腳本.沒啥好說的,照做.

    5. 避免重定向
    有一種經(jīng)常被網(wǎng)頁開發(fā)者忽略卻往往十分浪費(fèi)響應(yīng)時(shí)間的跳轉(zhuǎn)現(xiàn)象。這種現(xiàn)象發(fā)生在當(dāng)URL本該有斜杠(/)卻被忽略掉時(shí)。這時(shí)候會(huì)返回一個(gè)301的狀態(tài)碼,然后瀏覽器重新發(fā)起一次請(qǐng)求.在企業(yè)應(yīng)用里,重定向是我們?cè)谄髽I(yè)應(yīng)用中常用的技術(shù),不過用在網(wǎng)站項(xiàng)目上,您可要小心了,因?yàn)槠胀ǖ闹囟ㄏ蚱鋵?shí)是server在response header中設(shè)置http status=302,瀏覽器收到之后,判斷出是302,會(huì)重新發(fā)送一個(gè)請(qǐng)求,目標(biāo)地址是前一次返回中指定的地址.在網(wǎng)站項(xiàng)目中如果可以不用重定向就別用吧.如果您做企業(yè)應(yīng)用項(xiàng)目,ok,關(guān)系不大,您就放心的”定”吧.

    小節(jié),ahuaxuan把減少http請(qǐng)求次數(shù)分為了以上5個(gè)小點(diǎn),每個(gè)小點(diǎn)之后附加一些實(shí)例,大家可以根據(jù)這些點(diǎn)來判斷自己的項(xiàng)目是否可以有優(yōu)化的地方.


    使用cdn
    讓內(nèi)容更靠近用戶,這有啥好說呢,原理很簡(jiǎn)單,就是根據(jù)用戶瀏覽器所在機(jī)器的ip來判斷哪些服務(wù)器離用戶最近,瀏覽器會(huì)再次去請(qǐng)求這些最近的機(jī)器.一般的cdn服務(wù)商是通過開發(fā)自己的dns server來達(dá)到這個(gè)目的的.不過這個(gè)是通常情況哦,技術(shù)實(shí)力比較高,或者場(chǎng)景比較特殊的公司會(huì)開發(fā)自己的cdn.當(dāng)然不管怎么說,使用cdn肯定可以使頁面響應(yīng)更快(也包括音頻,視頻,圖片,文本文件,等等等等)

    減小返回?cái)?shù)據(jù)的體積
    1. 使用gzip壓縮返回?cái)?shù)據(jù)
    Gzip壓縮所有可能的文件類型是減少文件體積增加用戶體驗(yàn)的簡(jiǎn)單方法。比如本來400k的文件,壓縮一下之后只有50k-100k,那么網(wǎng)絡(luò)的流量就立刻下來了,壓縮的代價(jià)是服務(wù)器端要壓縮文件,需要消耗cpu,瀏覽器需要解壓文件,也需要消耗cpu,不過對(duì)于現(xiàn)代這么nb的pc,來說,瀏覽器解壓一下數(shù)據(jù)帶來的cpu消耗簡(jiǎn)直不值一提.所以您就壓吧.不過壓的時(shí)候要小心哦,有的瀏覽器在特定場(chǎng)景下會(huì)出去一些小bug,導(dǎo)致頁面不正常.比如ie6在跨域的時(shí)候可能會(huì)有些小麻煩,把這部分?jǐn)?shù)據(jù)的gzip去掉就可以了.

    2. 最小化js文件和css文件
    壓縮js可以使用JSMin或者YUI Compressor,后者同時(shí)可以壓縮css,這個(gè)也沒啥好說的,照做吧.

    3. 將css和js獨(dú)立成外部文件
    其實(shí)這一點(diǎn)也可以看成是區(qū)分不變數(shù)據(jù)和變化數(shù)據(jù).很多人喜歡在頁面商寫很多很多的js和css,這些數(shù)據(jù)其實(shí)都是不會(huì)變化的數(shù)據(jù),也就是說這些數(shù)據(jù)也是可以緩存在瀏覽器上的,通過把它們獨(dú)立成外部文件,可以把這些數(shù)據(jù)緩存起來.這樣做看上去是增加的請(qǐng)求的次數(shù),但是由于第一次請(qǐng)求之后該部分?jǐn)?shù)據(jù)已經(jīng)被緩存,所以第二次就無需再請(qǐng)求后端,減少了網(wǎng)絡(luò)帶寬的開銷.

    優(yōu)化Cookie

    1. 減小cookie體積
    能不放就別放吧,為啥呀,cookie就象鑰匙串,只有出門和回家得時(shí)候才用,但是一整天你都要帶在身上,麻煩不.
    2. 合理設(shè)置Cookie域
    由于二級(jí)域名可以拿到一級(jí)域名得cookie,那么如果,而二級(jí)域名之間確不能相互共享cookie,所以合理得設(shè)置cookie得域名也可以避免無必要得帶寬浪費(fèi)和響應(yīng)速度得增加.
    3. 設(shè)置合理的cookie過期時(shí)間
    該過期就過期,不要讓不必要的數(shù)據(jù)一直帶在身上走來走去.
    4. 使用域分離
    為圖片或者其他靜態(tài)資源文件使用子域或者建立新的獨(dú)立域名(申請(qǐng)新的域名),避免無必要的cookie傳輸,當(dāng)然也是要在有必要得情況下,圖片類網(wǎng)站肯定有必要,javaeye上得圖片并沒有使用域分離,所以我們得cookie其實(shí)會(huì)帶到壇子得圖片服務(wù)器上去,每次請(qǐng)求圖片都是如此(不過還好,壇子里沒有什么圖片,所以這方面的浪費(fèi)不大).

    小結(jié),其實(shí)cookie上得問題,單詞請(qǐng)求看上去也不是什么大問題,好像是無所謂得事情,就那么幾十個(gè)byte,至于嗎,不過大家都聽說過水滴石穿,繩鋸木斷的故事.所以該做的,我們還是要做,正所謂,勿以善小而不為,勿以惡小而為之.
    優(yōu)化瀏覽器加載
    1. 將css放在頁面頂部加載
    把樣式表放在文檔底部的問題是在包括Internet Explorer在內(nèi)的很多瀏覽器中這會(huì)中止內(nèi)容的有序呈現(xiàn)。瀏覽器中止呈現(xiàn)是為了避免樣式改變引起的頁面元素重繪。用戶不得不面對(duì)一個(gè)空白頁面。
          HTML規(guī)范清 楚指出樣式表要放包含在頁面的<head />區(qū)域內(nèi):“和<a />不同,<link />只能出現(xiàn)在文檔的<head />區(qū)域內(nèi),盡管它可以多次使用它”。無論是引起白屏還是出現(xiàn)沒有樣式化的內(nèi)容都不值得去嘗試。最好的方案就是按照HTML規(guī)范在文 檔<head />內(nèi)加載你的樣式表。

    2. 將js放在頁面底部加載
    腳本帶來的問題就是它阻止了頁面的平行下載。HTTP/1.1 規(guī)范建議,瀏覽器每個(gè)主機(jī)名的并行下載內(nèi)容不超過兩個(gè)。如果你的圖片放在多個(gè)主機(jī)名上,你可以在每個(gè)并行下載中同時(shí)下載2個(gè)以上的文件。但是當(dāng)下載腳本時(shí),瀏覽器就不會(huì)同時(shí)下載其它文件了,即便是主機(jī)名不相同。

    Js放在底部加載其實(shí)并不影響瀏覽器展示頁面,除非用戶會(huì)在js加載完成之前就調(diào)用某個(gè)js方法,比如說頁面剛展現(xiàn)到一半,但是恰好這一半里有一部分是調(diào)用了還未下載的js,這個(gè)時(shí)候就會(huì)出問題了,如果童子們遇到這種情況,可以把這部分js先加載.

        
    總結(jié)一下下:以上這些優(yōu)化點(diǎn)其實(shí)只是前端優(yōu)化的部分內(nèi)容,不過根據(jù)80/20原則,這些優(yōu)化點(diǎn)已經(jīng)覆蓋了80%的情況了,同時(shí)前端優(yōu)化其實(shí)也不是什么復(fù)雜的東西,原理上是很簡(jiǎn)單的,更多的是需要我們的實(shí)踐,因?yàn)槲覀兛赡軙?huì)碰到各種各樣的問題,而很多的這些問題其實(shí)一般是預(yù)測(cè)不到的.只有遇到過才知道.
    說的不對(duì)的地方請(qǐng)大家拍磚,或者童子們也可以把自己的經(jīng)驗(yàn)在這里和大家分享一下.代表其他童子表示十分的感謝.

    當(dāng)然,由于ahuaxuan水平有限,文章中難免有不到之處,還望不吝指正,謝謝.
    posted @ 2008-12-04 20:31 bt下載 閱讀(1547) | 評(píng)論 (3)編輯 收藏

    企業(yè)向國(guó)家工商總局申請(qǐng)對(duì)百度濫用市場(chǎng)支配地位進(jìn)行反壟斷調(diào)查,并處1.7億元罰款 bt吧。

      本報(bào)記者 韋文潔

      目前,國(guó)內(nèi)對(duì)百度的競(jìng)價(jià)排名雖然詬病頗多,但在制約手段的建立上處于真空狀態(tài),缺乏相應(yīng)的措施。在業(yè)界評(píng)論家看來,如果國(guó)內(nèi)搜索控制輿論沒有相關(guān)的法律法規(guī)來制裁,總有一天,網(wǎng)絡(luò)自由也將會(huì)淪為資本的附屬品 色即是空

      2008年的這個(gè)秋天,對(duì)北京百度網(wǎng)訊科技有限公司(以下簡(jiǎn)稱百度)來說,可謂多事之秋。

      10月31日,就在秋末的最后這幾天,受河北唐山人人信息服務(wù)有限公司法定代表人王冠玨的委托,北京市邦道律師事務(wù)所李長(zhǎng)青律師,把一冊(cè)厚達(dá)91頁16開本的《反壟斷調(diào)查申請(qǐng)書》,送到了國(guó)家工商總局反壟斷處一位官員手中,申請(qǐng)對(duì)百度濫用市場(chǎng)支配地位的反壟斷調(diào)查。據(jù)這位官員告訴他,這是反壟斷法實(shí)施以來,發(fā)生在網(wǎng)絡(luò)領(lǐng)域的第一例。

      而在此之前,9月8日,淘寶網(wǎng)“為杜絕不良商家欺詐”,首次向外界宣布屏蔽百度搜索鏈接,向其公正性公開提出抗議;9月12日,百度因被披露涉嫌收取300萬元保護(hù)費(fèi)屏蔽三鹿奶粉負(fù)面新聞,被卷入震驚全國(guó)的“三鹿問題奶粉”事件之中,成為公眾口誅筆伐的對(duì)象。

      更早一些,在今年的秋初,因質(zhì)疑“競(jìng)價(jià)排名”的貓膩,百度就被深圳律師黃維領(lǐng)告上法院,如果不是百度提出管轄權(quán)異議,此案恐怕已在深圳市福田區(qū)人民法院開庭審理。

      “發(fā)難”一場(chǎng)連接一場(chǎng),面對(duì)來自南北的不斷夾擊,百度這個(gè)“全球最大的中文搜索引擎”,如何將這股訴訟潮化險(xiǎn)為夷,巧渡搜索引擎行業(yè)所面臨的經(jīng)營(yíng)模式之困,化解新技術(shù)帶來的法律難題,成為業(yè)界關(guān)注的焦點(diǎn)。

      異常變化

      2007年初,曾有10年經(jīng)營(yíng)藥品生意的唐山人王冠玨,在工商局登記注冊(cè)了唐山人人信息服務(wù)有限公司,創(chuàng)辦了一個(gè)普及醫(yī)藥知識(shí)及招商的網(wǎng)站———全民醫(yī)藥網(wǎng)。

      為了提高網(wǎng)站的點(diǎn)擊率,增加客流量,全民醫(yī)藥網(wǎng)和百度河北代理商簽了一個(gè)《競(jìng)價(jià)排名協(xié)議》。

      所謂“競(jìng)價(jià)排名”,就是搜索引擎商推出的一種業(yè)務(wù)。當(dāng)用戶搜索一些常用詞語時(shí),從搜索引擎服務(wù)商購買了服務(wù)的廠商的名字就會(huì)排在搜索的前列。每當(dāng)用戶點(diǎn)擊搜索的結(jié)果進(jìn)入廠商的主頁時(shí),廠商就要向搜索引擎服務(wù)商繳納一次費(fèi)用,也就是搜索引擎的廣告收入。

      全民醫(yī)藥網(wǎng)和百度簽訂的這個(gè)競(jìng)價(jià)排名,參與時(shí)間為2008年3月至9月份,金額8.9萬元,排位于第3名,點(diǎn)擊一次最低價(jià)格為0.55元,最高為3.8元。

      參與競(jìng)價(jià)的最初幾個(gè)月,是全民醫(yī)藥網(wǎng)和百度的蜜月期。全民醫(yī)藥網(wǎng)做的全國(guó)廠家招商、招會(huì)員,在百度搜索排第一名。他們網(wǎng)站的客流,高峰時(shí)日瀏覽量達(dá)8000次,每月固定客戶以1000人的比例上漲。

      誰知前景開始看好的時(shí)候,因?yàn)槿襻t(yī)藥網(wǎng)要改版,6月至8月,全民醫(yī)藥網(wǎng)把競(jìng)價(jià)支付價(jià)格調(diào)到最低時(shí),異常便開始出現(xiàn)了。

      7月5日一上班,商務(wù)部經(jīng)理李娟就慌慌張張地跑來告訴王冠玨,“今天在百度里輸入全民醫(yī)藥網(wǎng)的網(wǎng)址,鏈接一下子突然少了,以前的八萬多條信息,只剩下了一個(gè)頁面4條記錄”。

      身為商人的王冠玨深知,訪問量就是網(wǎng)站的生命,新客戶來不了,老客戶不會(huì)來,做免費(fèi)的廣告,商家也不會(huì)干。從百度來的訪問量一直占全民醫(yī)藥網(wǎng)90%的客流量,如果不及時(shí)改變這種異常變化,全民醫(yī)藥網(wǎng)只能是“坐以待斃。”

      為了解決面臨的“滅頂之災(zāi)”,作為百度的一個(gè)客戶,王冠玨趕緊讓技術(shù)部長(zhǎng)王運(yùn)嶺,給百度總部和百度石家莊代理商發(fā)信和去電,反映這一異常變化。但百度的電話始終打不通。最后好不容易收到了石家莊百度的回信:“通常這種變化是正常的,是完全自動(dòng)的,并不表示會(huì)對(duì)個(gè)別網(wǎng)站進(jìn)行懲罰。”

      可是,讓王冠玨焦慮不已的是,到了7月10日,全民醫(yī)藥網(wǎng)的日訪問量驟減,從前一日的2961IP驟減為701IP。而后來以2008年7月10日為分界點(diǎn)的前后兩個(gè)月對(duì)比,全民醫(yī)藥網(wǎng)的月訪問量從前一個(gè)月的88095IP銳減至18340IP,日均訪問量從2936IP銳減至611IP,會(huì)員已經(jīng)在網(wǎng)上搜不到全民醫(yī)藥網(wǎng),網(wǎng)站幾乎沒人來光顧了。再和百度聯(lián)系,一點(diǎn)音信都沒有。

      7月14日,焦慮不已的王冠玨不得不再次給百度去信哀求:“就算是你們客服說的是因?yàn)橄到y(tǒng)自動(dòng)更新,但更新也不能差距這么大呀?現(xiàn)在幾乎就在百度里找不到帶著全民醫(yī)藥網(wǎng)域名的內(nèi)容了……請(qǐng)幫我們查出原因,速回郵件或致電。”

      但直到現(xiàn)在,他也沒有等來百度的郵件或回電。

      “降權(quán)懲罰”

      9月初,王冠玨給全民醫(yī)藥網(wǎng)換了一個(gè)域名,希望百度能夠收錄他們網(wǎng)站,但是一個(gè)月過去了,一條記錄都沒有。

      2008年9月25日,王冠玨在查詢谷歌、雅虎對(duì)全民醫(yī)藥網(wǎng)的收錄情況時(shí),結(jié)果分別顯示為6690條及3000多條,而其他的包括有道、搜狗,都比百度多。

      面對(duì)這種異常,王冠玨真是百思不解。經(jīng)過走訪大量的網(wǎng)站,咨詢行內(nèi)專家,翻閱大量資料后,發(fā)現(xiàn)他們也遭遇過類似的結(jié)果。

      一些站長(zhǎng)告訴他,之前在百度做了競(jìng)價(jià)排名,如果后來不做,很容易就被百度屏蔽了。比如:重慶某知名民營(yíng)醫(yī)院在建立自己的網(wǎng)站后,在百度、谷歌、雅虎等搜索引擎上搜索排名一直排第一。但是,從今年8月開始,用百度竟然再也搜索不到醫(yī)院網(wǎng)站了,但用谷歌、雅虎卻能夠搜索到,而且還是排位第一。這讓醫(yī)院感到十分疑惑,便以各種方式向百度反映這一情況,但都未得到令人信服的答復(fù)。迫于無奈,醫(yī)院負(fù)責(zé)人趕緊投錢參加百度的競(jìng)價(jià)排名,很快,醫(yī)院的網(wǎng)站又“神奇地”在百度上出現(xiàn)了。

      2005年10月至2006年4月,365數(shù)碼網(wǎng)曾在百度做競(jìng)價(jià)排名廣告。而當(dāng)他們停止續(xù)費(fèi),不再在百度上投放廣告后,竟然被百度“屏蔽”。

      據(jù)中搜網(wǎng)的技術(shù)專家介紹,所有的搜索結(jié)果都可以進(jìn)行人工干預(yù),所謂屏蔽就是在搜索程序中嵌入針對(duì)特定信息的“黑名單”,從而使機(jī)器自動(dòng)不去抓取指定域名的網(wǎng)頁,從而實(shí)現(xiàn)自己的營(yíng)銷目的。

      王冠玨的一位網(wǎng)友還告訴他,其代理的客戶大部分在行業(yè)中有較強(qiáng)的影響,網(wǎng)站也都具有相當(dāng)?shù)牧髁俊T谫徺I百度關(guān)鍵詞競(jìng)價(jià)之前,在百度搜索頁左邊的排序中,基本都能排在前幾名,而在購買了百度的關(guān)鍵詞競(jìng)價(jià)服務(wù)后,反而在首頁很難找到。

      “顯然,百度在非付費(fèi)的自然排序中有意下降客戶的排名,目的就是希望這些客戶對(duì)于關(guān)鍵詞競(jìng)價(jià)這種付費(fèi)服務(wù)產(chǎn)生依賴。”王冠玨的網(wǎng)友說。

      因此,早在2005年,一些網(wǎng)站站長(zhǎng)甚至結(jié)成了“反百度聯(lián)盟”,并且獲得了信息產(chǎn)業(yè)部備案序號(hào)(豫ICP備05009507)。據(jù)《瞭望》報(bào)道,聯(lián)盟的發(fā)起人郭振東,2004年發(fā)現(xiàn)自己創(chuàng)辦的文學(xué)網(wǎng)站美人魚社區(qū)被百度屏蔽。此后,他在與百度上海公司員工的接觸中獲悉,只要交6000元就能將被封的網(wǎng)站解禁,并承諾在一年內(nèi)不再屏蔽。因此,他認(rèn)為百度之所以對(duì)網(wǎng)站進(jìn)行屏蔽,是為了推廣百度的競(jìng)價(jià)排名服務(wù),遂發(fā)起“反百度聯(lián)盟”,收集百度公司對(duì)待站長(zhǎng)和網(wǎng)友不公正的證據(jù)。

      “沒在百度做競(jìng)價(jià)排名廣告前,還可以在百度上搜索到365數(shù)碼網(wǎng),現(xiàn)在卻搜不到了。早知道這樣,還不如一開始就不做呢。”該365數(shù)碼網(wǎng)負(fù)責(zé)人認(rèn)為,百度“封殺”365數(shù)碼網(wǎng)的目的,在于迫使其繼續(xù)交錢給百度做競(jìng)價(jià)排名廣告。

      “最令人不服氣的是,用什么評(píng)定中小網(wǎng)站該不該被屏蔽,這一系列的標(biāo)準(zhǔn)都是百度自己在操作,外人無法知道,更無法考證和干涉。”一位網(wǎng)友告訴王冠玨。

      看一看他人,比一比自己,王冠玨徹底明白了,因?yàn)樽约旱木W(wǎng)站開始有了4000以上的客流量,它一看你的IP這么高,開始能賺到錢,為什么還不到我這里來交錢?便給你的網(wǎng)站來了個(gè)“降權(quán)懲罰。”

      但百度企業(yè)市場(chǎng)部總監(jiān)舒迅曾對(duì)“屏蔽”一說斷然否認(rèn):“百度搜索引擎上是否收錄一個(gè)網(wǎng)站,與這個(gè)網(wǎng)站是否參與百度競(jìng)價(jià)排名推廣沒有任何關(guān)系。百度收錄的中文網(wǎng)站數(shù)是全球最多的,但并不承諾收錄每一個(gè)網(wǎng)站。”

    百度壟斷

      “百度一下”,幾乎已經(jīng)成為廣大網(wǎng)民最為常見的習(xí)慣性搜索。

      自7月份以來,不斷有客戶問王冠玨:“在網(wǎng)上為什么搜不到你們網(wǎng)站?”網(wǎng)民一般都使用百度,他們認(rèn)為在百度搜不到,就是在網(wǎng)上搜不到。

      李長(zhǎng)青律師認(rèn)為,百度的屏蔽行為對(duì)其他網(wǎng)站之所以構(gòu)成封殺是基于其獲得的市場(chǎng)支配地位。

      據(jù)相關(guān)資料表明,2008年第2季度,百度占據(jù)中國(guó)搜索引擎市場(chǎng)份額的64.4%。第3季度,坐擁中國(guó)搜索市場(chǎng)近2/3份額。到今年10月23日,百度網(wǎng)站發(fā)布公司新聞,已經(jīng)在中國(guó)搜索引擎市場(chǎng)穩(wěn)穩(wěn)占據(jù)70%以上市場(chǎng)份額。雖然它不過是一個(gè)工具,但它現(xiàn)在形成了一個(gè)霸主的地位。將對(duì)手遠(yuǎn)遠(yuǎn)拋在后面。

      《反壟斷法》第19條第一款第一項(xiàng)規(guī)定,有下列情形之一的,可以推定經(jīng)營(yíng)者具有市場(chǎng)支配地位:一個(gè)經(jīng)營(yíng)者在相關(guān)市場(chǎng)的市場(chǎng)份額達(dá)到二分之一的。上述資料表明,百度已經(jīng)完全獲得了中國(guó)搜索引擎市場(chǎng)的支配地位。

      正是因?yàn)榘俣染哂辛诉@樣的市場(chǎng)地位,其屏蔽行為才具有了封殺其他網(wǎng)站的能量和效果。百度也利用此舉,贏得了巨大的收益:2007年,百度年收入為17.444億元人民幣,比2006年增長(zhǎng)108.2%。而其2008年第二季度的財(cái)報(bào)顯示,收入突破一億美元。

      記者一位在北京經(jīng)營(yíng)網(wǎng)站的朋友則認(rèn)為,對(duì)于眾多中小網(wǎng)站來講,其絕大多數(shù)的流量都來自于百度搜索引擎這個(gè)“入口”。因?yàn)榻^大多數(shù)網(wǎng)民往往只能記住網(wǎng)站的名稱,然后通過搜索到達(dá)該網(wǎng)站。因此,擺在眾多網(wǎng)站面前的一個(gè)現(xiàn)實(shí)問題是,網(wǎng)站流量的訪問入口已經(jīng)被百度這些大搜索巨頭所壟斷,網(wǎng)站的生殺大權(quán)事實(shí)上已經(jīng)被掌握在了別人手中。一旦被搜索引擎“屏蔽”,就很有可能導(dǎo)致網(wǎng)站失去流量。對(duì)于搜索引擎“競(jìng)價(jià)排名”的方式,中小網(wǎng)站雖然不滿,但為了生存,大多數(shù)都敢怒不敢言。

      現(xiàn)在擺在他們面前的只有兩條路:如果想逃避被百度封殺的厄運(yùn),要么屈服于它,參與競(jìng)價(jià)推廣,任其宰割;要么向反壟斷部門舉報(bào),或到法院起訴,通過打官司,尋求公正。

      對(duì)王冠玨而言,擺在他面前的這兩條路,沒有一條坦途。

      “生死之戰(zhàn)”

      就在瀕臨絕望的時(shí)候,8月1日起施行的《反壟斷法》,讓王冠玨瞬間下定了決心:“我看到了希望。只要法律是公正的,哪怕我失敗,也要去摸這個(gè)老虎屁股。否則,你投入再多,由它來主宰,這種狀況永遠(yuǎn)也無法改變。”

      10月31日,在送往國(guó)家工商總局反壟斷處的《反壟斷調(diào)查申請(qǐng)書》中,李長(zhǎng)青律師認(rèn)為,百度對(duì)其他網(wǎng)站的封殺,是濫用市場(chǎng)支配地位的行為,造成兩個(gè)嚴(yán)重的社會(huì)后果:其一、百度的封殺行為在實(shí)際上消滅了許多網(wǎng)絡(luò)經(jīng)濟(jì)中的市場(chǎng)競(jìng)爭(zhēng)主體,從根本上破壞了公平的市場(chǎng)競(jìng)爭(zhēng)秩序,嚴(yán)重?fù)p害了社會(huì)主義市場(chǎng)經(jīng)濟(jì)的活力;其二、出于商業(yè)目的人工干預(yù)搜索結(jié)果的行為損害了社會(huì)大眾的利益,不符合公眾對(duì)于信息公開、客觀的要求。其行為與敲詐勒索無二。這種網(wǎng)絡(luò)霸權(quán)主義,不僅應(yīng)該受到道義上的譴責(zé),而且應(yīng)該受到行政和法律的制裁。

      他建議:執(zhí)法機(jī)構(gòu)對(duì)百度使用的搜索技術(shù)規(guī)則和搜索過程進(jìn)行調(diào)查;制定搜索技術(shù)規(guī)范和搜索市場(chǎng)服務(wù)規(guī)范,強(qiáng)化對(duì)搜索引擎服務(wù)的管理;責(zé)令百度停止其濫用市場(chǎng)支配地位封殺其他網(wǎng)站的違法行為,并處以1.7444億元人民幣的罰款(《中華人民共和國(guó)反壟斷法》第47條規(guī)定:經(jīng)營(yíng)者違反本法規(guī)定,濫用市場(chǎng)支配地位的,由反壟斷執(zhí)法機(jī)構(gòu)責(zé)令停止違法行為,沒收違法所得,并處上一年度銷售額百分之一以上百分之十以下的罰款。2007年百度全年?duì)I業(yè)收入為17.444億人民幣,根據(jù)以上規(guī)定,可以對(duì)其處以1.7444億元人民幣的罰款)。

      中國(guó)互聯(lián)網(wǎng)協(xié)會(huì)互聯(lián)網(wǎng)政策與資源工作委員會(huì)學(xué)術(shù)專家胡鋼曾對(duì)媒體表示,搜索引擎的“推廣方式”或“贊助商鏈接”在本質(zhì)上依然屬于廣告。但由于嶄新性,搜索引擎尚處在廣告法的監(jiān)管盲區(qū),這使得搜索引擎服務(wù)商得以明目張膽地大打“擦邊球”。

      中國(guó)政法大學(xué)副教授吳景明則認(rèn)為,我國(guó)《廣告法》第13條早已規(guī)定:廣告應(yīng)當(dāng)具有可識(shí)別性,能夠使消費(fèi)者辨明其為廣告。而搜索行業(yè)的競(jìng)價(jià)排名未能被明確劃歸到廣告范圍,類似搜索引擎這類新技術(shù)應(yīng)用帶來的問題該如何適用法律,目前尚無定論,“這凸顯我國(guó)相關(guān)立法的滯后”。

      互聯(lián)法網(wǎng)總監(jiān)趙占領(lǐng)也認(rèn)為:“這類事件反映出我國(guó)互聯(lián)網(wǎng)領(lǐng)域還存在很多法律空白或爭(zhēng)議之處。比如廣告法和反不正當(dāng)競(jìng)爭(zhēng)法如何適用于網(wǎng)絡(luò)環(huán)境下?搜索引擎運(yùn)營(yíng)商在用戶沒有購買競(jìng)價(jià)排名的情況下,不收錄用戶的網(wǎng)站究竟該如何定性?是否屬于強(qiáng)制交易行為?這都需要提供證據(jù)來證明搜索引擎運(yùn)營(yíng)商此舉的初衷是為了達(dá)成交易。”

      目前,國(guó)內(nèi)對(duì)百度的競(jìng)價(jià)排名雖然詬病頗多,但在制約手段的建立上處于真空狀態(tài),缺乏相應(yīng)的措施。在業(yè)界評(píng)論家看來,如果國(guó)內(nèi)搜索控制輿論沒有相關(guān)的法律法規(guī)來制裁,總有一天,網(wǎng)絡(luò)自由也將會(huì)淪為資本的附屬品。

      現(xiàn)在,也許是政府部門著手解決這個(gè)問題的最佳時(shí)間。10月31日,李長(zhǎng)青律師送材料到國(guó)家工商總局反壟斷處時(shí),一位官員告訴他:“內(nèi)部也正在開會(huì),研討這方面的問題呢。”

      在等待行政申請(qǐng)結(jié)果的同時(shí),他正忙著收集證據(jù),準(zhǔn)備一旦時(shí)機(jī)成熟,要與百度對(duì)簿公堂,展開一場(chǎng)面對(duì)面的“生死之戰(zhàn)”。而“一旦這個(gè)口子打開了,救活的就不僅僅是全民醫(yī)藥網(wǎng)這一家了,而是所有的中小網(wǎng)站和中國(guó)的互聯(lián)網(wǎng)經(jīng)濟(jì)。”李長(zhǎng)青律師說。

    posted @ 2008-11-09 22:08 bt下載 閱讀(229) | 評(píng)論 (0)編輯 收藏

    這是 Mashable bt搜集的最新 Web 開發(fā)工具箱,包括拖放式 Web 程序創(chuàng)建工具,代碼庫,項(xiàng)目管理,測(cè)試程序,以及支持各種編程語言的框架,從 Ajax 到 Ruby 到 Python。這是第二部分。

      參考與資料


    COfundOS - 一個(gè)討論開源軟件,尋找投資的平臺(tái)。 http://www.5a520.cn
    Mac Yenta - 獨(dú)立 Mac 開發(fā)者的社會(huì)化網(wǎng)絡(luò)平臺(tái)
    CorkDump - 一個(gè)關(guān)于常用資源(代碼片段,CSS,F(xiàn)lash 等)討論板。
    All Developers Network - 開發(fā)者社會(huì)化網(wǎng)絡(luò)
    CodePlex - 來自微軟的開源項(xiàng)目托管站點(diǎn)


    UnmatchList - 開發(fā)設(shè)計(jì)者的資源庫
    developerAnalytics - 社會(huì)媒體評(píng)價(jià)與報(bào)告,幫助你發(fā)現(xiàn)有潛力的社會(huì)媒體應(yīng)用。
    CollabFinder - 一個(gè)供開發(fā)設(shè)計(jì)者協(xié)同工作的地方。
    測(cè)試,監(jiān)控,Bug 跟蹤,項(xiàng)目管理



    CloudStatus - 對(duì) Web 上最流行云服務(wù)進(jìn)行觀察

    BetaBitz - 一個(gè)幫助你尋找 Beta 測(cè)試者的地方

    observu - 免費(fèi)的網(wǎng)站與服務(wù)器監(jiān)測(cè)服務(wù)

    UserFix - Bug 報(bào)告與功能請(qǐng)求站點(diǎn)

    OctaGate SiteTimer - 用來測(cè)試你的站點(diǎn)的訪問時(shí)延



    Cuzillion - 簡(jiǎn)單的頁面測(cè)試與檢查程序

    Mob4Hire - 為你的移動(dòng)應(yīng)用程序需要大量測(cè)試者

    Beanstalk - 一個(gè)托管的服務(wù),用來瀏覽跟蹤版本控制,包含對(duì)Basecamp 以及 Campfire 等同類服務(wù)的集成。

    BUGtrack - 項(xiàng)目管理,Bug 跟蹤

    UserZoom - 用戶體驗(yàn)測(cè)試平臺(tái)


    devunity - 曾是一個(gè) Beta 版 Bug 跟蹤服務(wù),現(xiàn)已成為社會(huì)化開發(fā)平臺(tái)
    BuiltWith - 對(duì)任何站點(diǎn)提供技術(shù)分析與 SEO 信息服務(wù)
    fixx - Bug 跟蹤,包含移動(dòng)設(shè)備界面與協(xié)同功能
    BugWiki - 一個(gè)簡(jiǎn)易的 Bug 跟蹤系統(tǒng)
    litmus - 基于 Web 的測(cè)試程序,在不同瀏覽器上檢查你的設(shè)計(jì)


    Bugtagger - 一個(gè)包含標(biāo)簽機(jī)制的 Bug 跟蹤程序,方便找到每個(gè) Bug 是與什么相關(guān)的
    FEED Validator - 驗(yàn)證你的 Atom, RSS 以及 KML 聚合服務(wù)
    pastebin - Debug 工具允許你協(xié)同工作以找到問題所在
    JUnit.org - 一個(gè)測(cè)試框架,編寫并執(zhí)行自動(dòng)測(cè)試程序
      Ruby 以及 Ruby on Rails 資源與工具


    Open Source Rails - 一個(gè)用來展示基于開源 Ruby on Rails 站點(diǎn)的地方
    Exceptional - Rails 程序異常跟蹤與管理工具
    TuneUp - 使用 Rails 插件檢查你的程序的性能
    heroku - Ruby on Rails平臺(tái),無需安裝配置,直接在瀏覽器中寫代碼。
    RSpec 1.1.8 - Ruby 的開發(fā)框架,包括 Scenario 框架與代碼示例框架



    Lovd By Less - 一個(gè)開源的 Ruby on Rails 社會(huì)網(wǎng)絡(luò)平臺(tái)
    Merb - 一個(gè) Ruby 框架,包含廣泛功能
    Camping - 一個(gè) Ruby 微框架
      Ajax, Java & JavaScript 資源與工具


    Javxs - 在線工具,將 HTML 轉(zhuǎn)換為 JavaScript
    frevvo - 一個(gè) Ajax 表單創(chuàng)建工具,包括 XML 支持與拖放式控制
    AjaxDaddy - Ajax 程序演示
    WaveMaker - 可視化,開源 Ajax 所見即所得編輯器
    AppJet - JavaScript 程序編寫平臺(tái)



    SproutCore - 一個(gè) JavaScript 框架,用來創(chuàng)建桌面質(zhì)量的 Web 程序
    Bungee Connect - Ajax Web 程序平臺(tái),跨瀏覽器支持
    Spring - 企業(yè) Java 應(yīng)用平臺(tái),旨在提高開發(fā)效率與程序質(zhì)量
    jQuery - 一個(gè)用于 Ajax Web 開發(fā)的 JavaScript 庫。
    KSS - 使用該框架,無需編寫任何代碼就可以開發(fā)基于 javaScript 的 UI
        PHP 資源與工具


    Flow3 - 一個(gè)最初用于 TYPO3 5.0 的 PHP 框架,但可以獨(dú)立使用
    Prado - 一個(gè)基于組件的 PHP 5 編程框架,面向?qū)ο螅录?qū)動(dòng)
      Perl 資源與工具


    Mason - 基于 Perl 的 網(wǎng)站開發(fā)引擎,包含 Debug, 模板等工具
      Flash 資源與工具


    OpenLaszlo - 富 Internet 平臺(tái),結(jié)合 Flash 與 DHTML,但只需一次編寫
      Python 資源與工具


    GTK+ - 一個(gè)用于 Python 的 GUI 開發(fā)工具套件
    Wing IDE - 專業(yè)的 Python 開發(fā)環(huán)境,提供30天試用
    Cheetah - 一個(gè)開源的,基于 Python 的模板引擎與代碼生成工具

    posted @ 2008-11-06 19:51 bt下載 閱讀(225) | 評(píng)論 (0)編輯 收藏

    新聞來源:mashable.com
    這是 Mashable bt搜集的最新 Web 開發(fā)工具箱,包括拖放式 Web 程序創(chuàng)建工具,代碼庫,項(xiàng)目管理,測(cè)試程序,以及支持各種編程語言的框架,從 Ajax 到 Ruby 到 Python。這是第一部分。

    Web 程序創(chuàng)建類


    DreamFace - 一個(gè)用來創(chuàng)建個(gè)性化 Web 程序的框架。

    Organic Incentive - 以拖放式界面創(chuàng)建 Web 飾件 http://www.5a520.cn

    dbFLEX - 商務(wù)程序開發(fā)平臺(tái)。

    app2you - 在線創(chuàng)建與定制 Web 程序。

    Qrimp - 一個(gè)便宜的數(shù)據(jù)庫平臺(tái),基于你周圍的數(shù)據(jù)(如 Excel)創(chuàng)建應(yīng)用程序。





    Lightspoke - 拖放式程序創(chuàng)建工具,動(dòng)態(tài)過濾,排序,真正的關(guān)系數(shù)據(jù)庫后臺(tái)。

    Tersus - 可視化程序創(chuàng)建工具,無需編寫代碼。

    Qt - 跨平臺(tái)應(yīng)用程序框架,可以同時(shí)開發(fā)應(yīng)用與界面。


    代碼庫與代碼搜索




    byteMyCode - 代碼搜索

    Snipplr - 幫你存儲(chǔ),管理所有代碼片段。

    ErrorKey - 錯(cuò)誤代碼搜索引擎。

    findJAR.com - JAR 文件搜索

    github - 代碼庫,既支持公共代碼,又支持私人代碼,私人代碼通過 SSH 以及 SSL 訪問。



    merobase - 搜索組件。

    Codebase - 代碼庫,技術(shù)支持與安裝部署跟蹤程序。

    CONFiles - 配置文件的在線存儲(chǔ)與分享

    CodeSnippets - 公共代碼庫,也支持私人代碼

    GWT-Ext - 免費(fèi)的,可下載的飾件庫


    開發(fā)環(huán)境,平臺(tái)與框架


    SocialGO - 社會(huì)化網(wǎng)絡(luò)托管平臺(tái),包括消息,視頻聊天,會(huì)員資料,照片分享,博客等
    Pringo - 社會(huì)化網(wǎng)絡(luò)平臺(tái),功能包括視頻,MP3 支持,圖片庫,圈子,podcasting 等。
    slinkset - 一個(gè)用于創(chuàng)建社會(huì)化新聞?wù)军c(diǎn)的在線平臺(tái)
    iWidgets - 社會(huì)化 Syndication 平臺(tái),允許你將你的內(nèi)容聚合到社會(huì)化網(wǎng)絡(luò)
    WackWall - 一個(gè) Hosted 的社會(huì)化網(wǎng)絡(luò)平臺(tái)




    WhiteLabelDating.com - 一個(gè)創(chuàng)建約會(huì),社會(huì)網(wǎng)絡(luò),社區(qū)站點(diǎn)的平臺(tái),允許以自己公司的名義創(chuàng)建。
    ONEsite - 社會(huì)網(wǎng)絡(luò)平臺(tái),包括博客,照片與視頻庫,評(píng)分與標(biāo)簽,消息板,私人消息等
    jinity - 免費(fèi)的社會(huì)網(wǎng)絡(luò)平臺(tái),包括消息板,聊天,圈子,日志,投票,新聞等
    Magnify.net - 網(wǎng)站視頻工具,包括全套媒體工具
    ShoutEm - 微博客與社會(huì)網(wǎng)絡(luò)平臺(tái)



    Soceeo - 社會(huì)網(wǎng)絡(luò)平臺(tái),包含文件分享,新聞,投票等
    Swift - 移動(dòng)站點(diǎn)創(chuàng)建工具,包括多種設(shè)計(jì)選項(xiàng),支持 RSS Feed,多媒體等
    SnappVille - 社會(huì)網(wǎng)絡(luò)平臺(tái),包括組,博客工具,即時(shí)消息等
    Ning - 社會(huì)網(wǎng)絡(luò)平臺(tái),允許使用自己的品牌,包括會(huì)員資料,事件列表,甚至 Facebook 集成。
    mixxt - 社會(huì)網(wǎng)絡(luò)平臺(tái),包括事件,論壇等
    zembly - 一個(gè)用來創(chuàng)建社會(huì)應(yīng)用的的平臺(tái),目前處于 Beta 版。Yuku - 一個(gè)社區(qū)平臺(tái),可定制,擁有很強(qiáng)大的系統(tǒng)管理工具SocialEngine - 基于 PHP 的社會(huì)網(wǎng)絡(luò)平臺(tái),功能包括 multi-part profiles,子網(wǎng),搜索友好 URL,博客,圈子等。Cappuccino - 一個(gè)用來創(chuàng)建桌面品質(zhì) Web 程序的開源框架Jaws - 一個(gè)用戶友好 CMS 平臺(tái)。   綜合開發(fā)工具


    Tabifier - 對(duì)你的代碼進(jìn)行自動(dòng)縮進(jìn)。
    Sms2do - 一個(gè)用來評(píng)測(cè)和演示 SMS 程序的免費(fèi)工具。
    Pretty Printer - 源代碼格式化工具,支持 PHP, JavaScript, CSS 等
    Jitterbit - 一個(gè)開源集成方案,提高可擴(kuò)充性與性能
    Bitizer - 二進(jìn)制,十進(jìn)制,16進(jìn)制,Base 36 以及 ASCII 轉(zhuǎn)換工具



    thmbnl - 顯示你站點(diǎn)中那些鏈接網(wǎng)頁的縮略圖
    ID Selector - 一個(gè) OpenID 工具
    consoleFISH - 免費(fèi)的,基于 Web 的 SSH 服務(wù)器訪問
    form site - 用來創(chuàng)建自定義表單
    99Polls - 用來創(chuàng)建投票與調(diào)查



    Warehouse - 一個(gè)非常漂亮的代碼庫瀏覽服務(wù),支持多代碼庫以及非常完善的權(quán)限控制
    rendur 2.1 - 一個(gè)沙箱程,讓你一邊寫代碼,一邊生成頁面
    Languify - 翻譯管理系統(tǒng)
    ROR Sitemap Generator - 顧名思義,這是一個(gè) ROR 網(wǎng)站地圖生成工具
    MicroMaps - 用來生成交互式地圖,放在你的網(wǎng)站



    Newsfeed Maker - 為你的網(wǎng)站或博客創(chuàng)建 News Feed
    WriteMaps - 網(wǎng)站地圖在線生成工具
    Project Kenai - 免費(fèi)的開源項(xiàng)目或代碼托管站點(diǎn)
    Launch Splash - 為你還沒有開通的網(wǎng)站免費(fèi)生成一個(gè)歡迎頁面
    Browser Shell - 基于瀏覽器的 SSH 工具
    foigo - 創(chuàng)建自定義表單,調(diào)查,以及數(shù)據(jù)庫AggData - Premade lists for your development projects.SnapCasa - 網(wǎng)站縮略圖工具Versionshelf - 代碼庫安全管理   Mashups 與 APIs


    The Echo Nest - 音樂相關(guān)的開發(fā)服務(wù) API,包括歌手資料,音樂推薦等功能
    Zeep Mobile - 為你的站點(diǎn)添加基于文本的消息系統(tǒng)
    Clickatell - 一個(gè)短消息網(wǎng)關(guān),讓你的網(wǎng)站通過多中連接方式發(fā)短消息
    Nonoba - 在線游戲開發(fā) API,支持多玩家。
    Zong - 移動(dòng)支付平臺(tái),包含開發(fā) API



    Web Shots Pro - 一個(gè) API,開發(fā)者可用來在他們的程序中添加網(wǎng)站縮略圖。
    Pushpin - 一個(gè)簡(jiǎn)單易用的在線地圖 API,支持大量標(biāo)記以及眾多其它功能
    Datamash - Create widgets and mashups for your site with information anywhere on the Web.借助網(wǎng)絡(luò)上的眾多信息為你的站點(diǎn)創(chuàng)建 widgets 與 mashups
    Spicy Pipes - Mashup builder.

    posted @ 2008-11-06 19:50 bt下載 閱讀(257) | 評(píng)論 (0)編輯 收藏

    原文作者:miguelcarrasco
    原文鏈接:Who Wants To Beat-Google?
    翻譯:小豬哥

    誰不想打敗Google呢?很宏偉的目標(biāo),但怎樣做到呢?每個(gè)人對(duì)此都有自己的魔幻方法。微軟一度要以440億美元收購Yahoo!,還在R&D投資 bt幾十億,縱然財(cái)力如此雄厚,他能做到么?有人認(rèn)為需要更多的網(wǎng)頁檢索,有人認(rèn)為應(yīng)當(dāng)有更好的界面,這個(gè)問題的答案仁者見仁,智者見智。

        而且現(xiàn)在來做這件事情(打敗Google)再合適不過。隨著經(jīng)濟(jì)危機(jī)的來臨,大批大批的web 2.0 公司即將破產(chǎn),那些僅僅依賴互聯(lián)網(wǎng)生存的公司也即將倒閉。即便強(qiáng)如Google也在去年受到了沖擊,其股價(jià)去年700美元每股,而今跌到286(作者發(fā)稿時(shí))。現(xiàn)在看來,互聯(lián)網(wǎng)免費(fèi)的午餐已經(jīng)消失。

        然而微軟卻一直保持著強(qiáng)勁的勢(shì)頭,因?yàn)樗浅6嘣以谝粋€(gè)領(lǐng)域做得實(shí)在太優(yōu)秀了——軟件!他有著難以想象的money,手中有難以置信的全球智慧人群(接近100,000雇員),同時(shí)他還擁有最富有夢(mèng)想的一些領(lǐng)導(dǎo)者在運(yùn)籌帷幄。如果有誰能夠做出更好的搜索引擎,那毫無疑問就是微軟。而Google會(huì)退縮么,當(dāng)然也不會(huì)。

    社交圖(Social Graph)


    Facebook經(jīng)常談?wù)?/font>的Social Graph著實(shí)強(qiáng)大,因此Facebook得以很了解你。他知道你的朋友是誰、你住在哪里、你在哪兒工作……他有圖片、video以及你感興趣的東西。他甚至知道你在哪個(gè)社交圈、你想?yún)⒓邮裁椿顒?dòng)。因而可以說Facebook比你的朋友都了解你。

    搜索怎么了(What’s Wrong With Search Today?)

        當(dāng)我試著用“GAC”一類的來搜索的時(shí)候,返回的結(jié)果令我感到荒唐——加拿大抵制協(xié)會(huì)(Geological Association of Canada)。我是一個(gè)軟件開發(fā)者,F(xiàn)acebook、Twitter和LinkedIn 都知道這一點(diǎn),但是Google對(duì)此一無所知。所以返回的有效搜索寥寥無幾。我媽媽搜索一個(gè)關(guān)鍵詞跟我搜索一個(gè)關(guān)鍵詞得到的返回完全相同。但是我媽媽喜愛 的是手工藝,我喜歡的是軟件開發(fā),我們應(yīng)該得到不同的結(jié)果才對(duì)。

        為什么沒有人利用社交圖的數(shù)據(jù)呢?單純拷貝Google搜索模式、換個(gè)Logo是行不通的,人們更換搜索需要理由。在搜索中添加內(nèi)容才是出路。

        比爾蓋茨在過去的幾年里一而再再而三地提到:搜索的道路還很長(zhǎng)。幾個(gè)月前我聽到的解決方案——新的界面、一直鼠標(biāo)滾動(dòng)的搜索結(jié)果(never ending scrolling),這些顯然不是比爾蓋茨想說的。Scrolling endlessly所以你就不用選頁了?這顯然不是解決方式。

        微軟真正應(yīng)當(dāng)做到的是:當(dāng)用Google和Live Search搜索的時(shí)候,Live Search返回的結(jié)果更好。而且不是好一點(diǎn),要好很多才行。

    微軟能做什么(So What Can Microsoft Do?)

        毫無疑問,微軟有業(yè)內(nèi)最優(yōu)秀的開發(fā)者、架構(gòu)師和工程師,同樣也有大筆大筆的錢可以投到搜索中(這一點(diǎn)從他購買Yahoo! 就能夠看出來)。然而微軟要想贏得搜索戰(zhàn)所缺少的東西也很明了:他們需要?jiǎng)?chuàng)意和行動(dòng)路線,也即“作戰(zhàn)計(jì)劃”。Windows, Internet Explorer和Office,微軟當(dāng)年都不是第一個(gè),但他做出了比其他操作系統(tǒng)更好的操作系統(tǒng),比其他office套件更好的office套件,比其 他瀏覽器更好的IE,而且他還讓所有這些應(yīng)用能夠無縫地運(yùn)行在一起。所以如果微軟擁有戰(zhàn)略,并且能夠正確實(shí)施,Live Search將會(huì)迅速得到難以想象的市場(chǎng)占有率。

    Live Search 與Facebook關(guān)聯(lián)(Live Search and Facebook Connect)

        微軟應(yīng)當(dāng)充分利用Facebook connect,并將之與Live Search關(guān)聯(lián)。使用Facebook connect,F(xiàn)acebook用戶能夠在Microsoft Live Search中關(guān)聯(lián)到他們資料數(shù)據(jù)和認(rèn)證證書。通過關(guān)聯(lián)搜索、結(jié)合用戶的資料數(shù)據(jù),這個(gè)搜索就是“終極搜索引擎”。

    Microformats將是搜索的未來(Microformats are the future of Search)


        Microformats比其他任何瀏覽器都好,以hCalander, hCard和 hReview開始。如果你還從未聽過Microformats,趕緊查查,你就會(huì)知道他為什么這么重要。到目前為止,網(wǎng)絡(luò)上大部分的數(shù)據(jù)都是完全無序的。舉個(gè)例子你輸入“Contact Miguel Carrasco”搜索,你會(huì)搜到我的博客但僅此而已。但你想要找到的是我的聯(lián)系卡片。下面是我使用hCalander Microformat來為Winnipeg.net User Group創(chuàng)建一個(gè)事件的實(shí)例。

       1: <div class="vevent" id="hcalendar-Winnipeg-.net-User-Group-September-Event">
       2:     <a class="url" >
       3:     <abbr class="dtstart" title="2008-09-30T06:00-06:0000">September 30, 2008  6</abbr> –
       4:     <abbr class="dtend" title="2008-09-30T08:00-06:00">8am</abbr> : 
       5:     <span class="summary">Winnipeg .net User Group September Event</span> at
       6:     <span class="location">17th Floor - One Lombard Place - Winnipeg, Manitoba, Canada</span></a>

       7:     <div class="description">What could possibly be better than enjoying some free pizza and pop with your peers while be entertained / educated by a presentation on a single .Net topic? Well, how about an open forum that includes some of the hottest topics in software development to date?! To keep the meeting energized, we will be limiting each topic to 20 minutes, and what's more, each topic will have a subject matter expert on hand to facilitate the session.
       8: 
       9:     Come prepared with questions, project stories, and ideas to one of the most unique user group sessions we have ever had.
      10: 
      11:     Topics will include:
      12: 
      13:     What is BizTalk
      14:     A Real World Silverlight Application
      15:     What is NHibernate
      16:     Why Continuous Integration Is Critical
      17:     Open Forum Free-for-All Session</div><div class="tags">Tags:
      18:     <a rel="tag" >winnipeg</a><a rel="tag" > user group</a><a rel="tag" > .net</a><a rel="tag" > microsoft</a></div>
      19: 
      20: </div>

        一個(gè)支持Microformat的搜索引擎可以在搜索結(jié)果中得到正確的信息,并且鏈接到網(wǎng)址來為事件注冊(cè)

    完美的搜索界面(The Complete Search Interface)

        大家也許都忘記了,Google剛誕生出來的那會(huì),沒有blogs,Video也不大,F(xiàn)acebook和其他社交網(wǎng)絡(luò)還在娘胎呢。然而搜索的未來在于內(nèi)容。人們每月花費(fèi)成百上千個(gè)鐘頭在社交網(wǎng)絡(luò)、新網(wǎng)址和博客。他們持續(xù)地向這些玩意中提供了大量他們的信息:喜歡什么?朋友是誰?下周做什么?現(xiàn)在什么心情?未來三周可能去哪玩……

        我個(gè)人就至少在網(wǎng)絡(luò)上使用至少20種不同的社交服務(wù),所以說搜索引擎不能只返給我簡(jiǎn)單的數(shù)據(jù),而應(yīng)當(dāng)利用這些數(shù)據(jù)返給我我想要的內(nèi)容。比如,我已經(jīng)在網(wǎng)上吵了好幾天說我下周要去邁阿密。

        在Facebook,我創(chuàng)建了幾個(gè)我將要在邁阿密參加的活動(dòng);在Digg,我dugg了幾個(gè)水中呼吸器的信息;在Last.fm,我創(chuàng)建了幾個(gè)標(biāo)題為“Miami Plane Ride”的音樂列表。在Facebook我從朋友那兒收到了幾個(gè)回帖稱我不應(yīng)當(dāng)錯(cuò)過邁阿密的幾個(gè)酒吧和跳舞俱樂部。其他朋友推薦了那兒的幾處海灘,還給了照片。

        如果我去Google搜索跳舞俱樂部,最頂上的三個(gè)搜索結(jié)果跟我要找的一點(diǎn)關(guān)系都沒有。如圖:



    圖片11
        正如我說的,沒有一個(gè)搜索結(jié)果對(duì)我有用,是不是我的搜索條件太為難Google了?于是我又輸入了“Miami”,讓我們?cè)倏纯唇Y(jié)果:


    圖片22

        現(xiàn)在起碼我得到了一些結(jié)果能讓我看到邁阿密的跳舞俱樂部,但是哪個(gè)是朋友推薦我的呢?為什么我要的結(jié)果不能直接出現(xiàn)在我的面前?為什么沒有圖片,或者最好再有video?消費(fèi)者的評(píng)論在哪兒呢?

        使用Live Complete Search,,輸入“跳舞俱樂部”,迅速在我的搜索結(jié)果中出現(xiàn)了內(nèi)容,并且將結(jié)果局限到了邁阿密。并不是因?yàn)?/font>我想去邁阿密,搜索才得到這樣的結(jié)果,而是因?yàn)槲襱witter了我的朋友問他們邁阿密最好的跳舞俱樂部在哪兒,因此,搜索找出了我想要的結(jié)果。



    圖片33

        第一條結(jié)果是Nikki Beach,正是我朋友告訴我的那個(gè)。搜索中還有一張圖片,他們留給我的評(píng)論也能在搜索頁面中看到,還有電話號(hào)碼也以microformats的形式出現(xiàn) 在網(wǎng)頁中,我還能夠在這兒使用Twitter, Digg或者 Facebook得到更詳細(xì)的信息。而且,Live Complete Search知道我在Last.FM創(chuàng)建了一個(gè)Miami播放列表,所以還在搜索中加入了一個(gè)鏈接。

        當(dāng)然這只是個(gè)例子,但我想從中你已經(jīng)能夠看到了精髓。

    Building Live Social Profile
        Google已經(jīng)證明你并不需要擁有所有的數(shù)據(jù),因?yàn)橛腥藭?huì)提供而Google只是幫你找到它們,令人感到發(fā)笑的是許多企業(yè)紛紛克隆Google的方法。 微軟有互聯(lián)網(wǎng)上第一位的IM——MSN Messenger,每個(gè)用戶都有一個(gè)Live 賬號(hào),有些人還有Live Spaces的賬號(hào)。我不知道你怎樣,但在我看來使用Live Spaces的并不多。我點(diǎn)擊了一下我MSN的好友,發(fā)現(xiàn)很多人從未用過Live Spaces,即使有使用的人,可能使用的幾率也不及Facebook之類的百分之一。

        我的建議是微軟應(yīng)當(dāng)設(shè)法將Live Spaces變成人氣旺盛的(“Live”) Spaces,從而用戶可以通過互聯(lián)網(wǎng)將他們的社交狀況傳上去,這將創(chuàng)建一個(gè)終極社交檔案(social profile)和終極個(gè)人網(wǎng)頁(social “my page”)。


    圖片44
    建議界面(The Proposed Interface)

        建議的Live Search的界面非常簡(jiǎn)單。它默認(rèn)提供完整的搜索容量,包含互聯(lián)網(wǎng)上的一切并將搜索結(jié)果放在合適的位置。比如,使用完全搜索,你會(huì)得到一些網(wǎng)頁、 blog、帖子和一些視頻,也可能有寫Digg文章。如果只想搜索自己的社交圖呢?沒問題,只需要點(diǎn)擊“Social”,搜索結(jié)果馬上只呈現(xiàn)出與你有關(guān)的 結(jié)果。

        而且,Live Search的界面中能夠插入許多過濾器,比如“搜索”和“兒童”。學(xué)校可以管理網(wǎng)絡(luò)從而只允許“搜索”模式,父母可以管好自己的孩子只允許“兒童”模 式。通過Live Spaces和 Live Profile連接這些系統(tǒng),微軟將創(chuàng)建出比Google PageRank強(qiáng)大許多的搜索,用戶的天平也開始擺向了這邊。



    圖片55
    搜索的最終思想(Final Thoughts on Search)

        希望你能夠意識(shí)到,社交內(nèi)容、microformats、和一個(gè)能夠提供整個(gè)網(wǎng)絡(luò)的完美界面將是搜索的下一次飛躍。擁有更加接近社交圖的搜索結(jié)果比PageRank或者PageRank的克隆更容易統(tǒng)計(jì)互聯(lián)網(wǎng)

    posted @ 2008-11-05 21:57 bt下載 閱讀(218) | 評(píng)論 (0)編輯 收藏

    毋庸置疑,對(duì)于所有研究互聯(lián)網(wǎng)新媒體公司的同仁們而言,blogbus是一個(gè)絕佳的案例,他不是BT bsp。

    1,在門戶BSP大舉進(jìn)攻下,專業(yè)BSP日漸沒落。blogbus偏安于上海,能發(fā)展的有聲有色,不易。剛看到Jenny發(fā)的blogbus六周年的活動(dòng)。可以說,blogbus的發(fā)展路線值得所有web2.0公司學(xué)習(xí)。

     編者注:如在百度中搜索 甜性澀愛色即是空 愛的色放出現(xiàn)的問題說知道了。

    2,blogbus能走到現(xiàn)在,跟公司團(tuán)隊(duì)的黃金組合關(guān)系很大。資深的互聯(lián)網(wǎng)人士:橫戈;資深媒體研究專家:魏武揮;資深廣告營(yíng)銷界人士:jenny。我想,國(guó)內(nèi)所有希望通過互聯(lián)網(wǎng)賺錢的web2.0公司都應(yīng)該參考下這種團(tuán)隊(duì)。不管是思路、見地。還有資源,客戶的說教。

    3,blogbus走出的商業(yè)模式,將是未來很長(zhǎng)一段時(shí)間,不少國(guó)內(nèi)2.0公司必須的一步。原因很簡(jiǎn)單,中國(guó)互聯(lián)網(wǎng)廣告規(guī)模雖然上漲很快,但依然停留在初級(jí)階段,缺乏專業(yè)細(xì)分的廣告網(wǎng)絡(luò)(代理)公司推動(dòng)。加上客戶認(rèn)知度較低,web2.0公司必須肩負(fù)推動(dòng)廣告挖掘的重任。

    4,所以,細(xì)分的廣告網(wǎng)絡(luò)(代理)公司在國(guó)內(nèi)會(huì)越來越有前景,其中一部分會(huì)來源于公關(guān)公司的升級(jí),另一部分會(huì)來自于當(dāng)下大量掌握廣告客戶投放資源的4A公司;再有一個(gè)就是新媒體或者是社會(huì)化媒體公司自身,在這點(diǎn)上blogbus和feedsky都是個(gè)例子。David Wolf說,“中國(guó)的問題在于我們點(diǎn)子的太簡(jiǎn)單”,其實(shí)更準(zhǔn)確點(diǎn)說是缺專營(yíng)的廣告營(yíng)銷公司。

    5,所以,有人會(huì)問:blogbus是廣告公司,還是互聯(lián)網(wǎng)公司?其實(shí),blogbus作為一個(gè)新媒體或者是社會(huì)化媒體平臺(tái),已經(jīng)聚集了百萬級(jí)的人群,背靠這些人群挖掘出了不小的商業(yè)價(jià)值,這已經(jīng)說明了一切。很多更大用戶量級(jí)的公司,尚不及此。你說google是互聯(lián)網(wǎng)公司,還是廣告公司?除了不斷膨脹的互聯(lián)網(wǎng)業(yè)務(wù),google也正在成為更大的廣告代理或分銷商。所以,我說過,新媒體要變成廣告公司

    6,blogbus最近推出的幾個(gè)業(yè)務(wù),非常值得把玩。一個(gè)是基于blog平臺(tái)推出的SNS功能,我非常認(rèn)同魏武揮的說法,因?yàn)橛脩艉蜖I(yíng)銷需求去增加blog平臺(tái)的互動(dòng)功能,顯然SNS是增加互動(dòng)關(guān)聯(lián)的成熟方式。但絕不是把blog變成一個(gè)SNS平臺(tái)。

    7,另一個(gè)更有意思的則是《城客》,簡(jiǎn)單說,城客是一個(gè)依托于blogbus平臺(tái)的雜志;它其實(shí)是blogbus線上資源的一個(gè)延伸(內(nèi)容低成本+現(xiàn)有用戶群),這也是我看好它的一個(gè)因素;趕巧的是,同期還有一個(gè)純粹靠整合網(wǎng)上內(nèi)容的印刷雜志《博客天下》。形式相同,思路卻是迥異。

    8,我記得,blogbus下面還有一個(gè)做口碑營(yíng)銷的“吆喝城”。

    9,blogbus會(huì)成為一種現(xiàn)象,尤其是在冬天。

    posted @ 2008-11-03 11:34 bt下載| 編輯 收藏

    TreeMap是紅黑樹算法的實(shí)現(xiàn),實(shí)現(xiàn)了SortedMap接口,要注意的是它不在使用哈希表,存儲(chǔ)方式是一個(gè)特殊的二叉樹,有關(guān)紅黑樹:
    http://baike.baidu.com/view/133754.htm  http://www.bt285.cn

    這篇文章介紹的不錯(cuò),我之前沒有聽說過二叉樹,我就是看這篇文章加上看一下TreeMap的源代碼才搞懂紅黑樹算法的.

     

    這里不打算研究TreeMap的源代碼了,因?yàn)橥耆且粋€(gè)算法的實(shí)現(xiàn),如果對(duì)這個(gè)算法不了解,肯定看不懂,我也有很多地方不是沒有完全看明白,這里就談?wù)凾reeMap的使用吧.

     

     

    TreeMap的聲明:public class TreeMap extends AbstractMap implements SortedMap,Cloneable, java.io.Serializable
    所以我們要知道SortedMap接口:
    SortedMap表示的是一個(gè)排序的Map
    public interface SortedMap extends Map
    增加了幾個(gè)方法的定義
    SortedMap headMap(Object toKey)
    SortedMap tailMap(Object fromKey)
    SortedMap subMap(Object fromKey, Object toKey)
    Object firstKey()
    Object lastKey()

     

     

    既然TreeMap是有序的,自然要求元素是可以比較大小的,如果構(gòu)造函數(shù)指定Comparator的話,就使用這個(gè)Comparator比較大小,如果沒有指定Comparator的話,就使用自然排序(元素要實(shí)現(xiàn)Comparable接口).如果這兩個(gè)都不可用,就等著出錯(cuò)吧.

    現(xiàn)看一下該接口的定義:
    public interface Comparable{
       public int compareTo(Object o);
    }
    該接口定義類的自然順序,實(shí)現(xiàn)該接口的類就可以按這種方式排序.
    一般要求:
    e1.equals((Object)e2)和e1.compareTo((Object)e2)==0具有相同的值,
    這樣的話我們就稱自然順序就和equals一致.
    這個(gè)接口有什么用呢?
    如果數(shù)據(jù)或者List中的元素實(shí)現(xiàn)了該接口的話,我們就可以調(diào)用Collections.sort或者Arrays方法給他們排序.

    如果自然順序和equals不一致的話,如果出現(xiàn)在Sorted Map和Set里面,
    就會(huì)出現(xiàn)預(yù)想不到的邏輯錯(cuò)誤,可能你調(diào)用add的時(shí)候添加不了,而集合里面確沒有這個(gè)元素.具體的討論要接口哈希表的應(yīng)用.

     

     

     

    public interface Comparator {
      int compare(Object o1, Object o2);
      boolean equals(Object obj);
    }

    定義了兩個(gè)方法,其實(shí)我們一般都只需要實(shí)現(xiàn)compare方法就行了,因?yàn)轭惗际悄J(rèn)從Object繼承
    所以會(huì)使用Object的equals方法.
    Comparator一般都作為一個(gè)匿名類出現(xiàn),對(duì)于沒有實(shí)現(xiàn)Comparable的對(duì)象的集合,排序的時(shí)候
    需要指定一個(gè)Comparator.

    這里舉例說明
    對(duì)于實(shí)現(xiàn)了Comparable的類我們就用最簡(jiǎn)單的Integer
    List list=new ArrayList();
    list.add(new Integer(3));
    list.add(new Integer(53));
    list.add(new Integer(34));
    Collections.sort(list);

    對(duì)于沒有實(shí)現(xiàn)Comparable的,我們就用Object,按照hashCode大小來排序.
    List list= new ArrayList();
    list.add(new Object());
    list.add(new Object());
    list.add(new Object());
    Collections.sort(list,new Comparator(){ public int compare(Object o1, Object o2){
                        return (o1.hashCode()-o2.hashCode());
    })

    因?yàn)槭嵌鏄?所以一般查找時(shí)間復(fù)雜度為 o(lg(n)),這個(gè)效率當(dāng)然沒有HashMap的效率高.不過TreeMap比HashMap功能強(qiáng)大,如果不需要排序的話當(dāng)然不會(huì)用TreeMap,如果需要排序的話,HashMap無法勝任,當(dāng)然要用TreeMap了,它可以求子Map.所以這個(gè)是適用場(chǎng)合問題,無法比較他們.
     
    另外,我們也習(xí)慣了,有Map就會(huì)跟一個(gè)Set,我們都可以猜到TreeSet和通過TreeMap實(shí)現(xiàn)的一個(gè)SortedSet的實(shí)現(xiàn).不過我覺的TreeSet好像比TreeMap用的場(chǎng)合多一些,求子集是很常用的呀!!

    posted @ 2008-10-30 20:59 bt下載 閱讀(3288) | 評(píng)論 (1)編輯 收藏

    以前我一直以為File#renameTo(File)方法與OS下面的 move/mv 命令是相同的,可以達(dá)到改名、移動(dòng)文件的目的。不過后來經(jīng)常發(fā)現(xiàn)問題,真的很bt,File#renameTo(File)方法會(huì)返回失敗(false),文件沒有移動(dòng),又查不出原因,再后來干脆棄用該方法,自己實(shí)現(xiàn)一個(gè)copy方法,問題倒是再也沒有出現(xiàn)過。

    昨天老板同學(xué)又遇到這個(gè)問題,F(xiàn)ile#renameTo(File)方法在windows下面工作的好好的,在linux下偶爾又失靈了。回到家我掃了一遍JDK中File#renameTo(File)方法的源代碼,發(fā)現(xiàn)它調(diào)用的是一個(gè)本地的方法(native method),無法再跟蹤下去。網(wǎng)上有人說該方法在window下是正常的,在linux下面是不正常的。這個(gè)很難說通,SUN不可能搞出這種平臺(tái)不一致的代碼出來啊。

    后面在SUN的官方論壇上看到有人提到這個(gè)問題“works on windows, don't work on linux”,后面有人回復(fù)說是“file systems”不一樣。究竟怎么不一樣呢?還是沒有想出來...

    后面在一個(gè)論壇里面發(fā)現(xiàn)了某人關(guān)于這個(gè)問題的闡述:
    In the Unix'esque O/S's you cannot renameTo() across file systems. This behavior is different than the Unix "mv" command. When crossing file systems mv does a copy and delete which is what you'll have to do if this is the case.

    The same thing would happen on Windows if you tried to renameTo a different drive, i.e. C: -> D:
    終于明白咯。

    做個(gè)實(shí)驗(yàn):

  • File sourceFile = new File("c:/test.txt");   
  • File targetFile1 = new File("e:/test.txt");   
  • File targetFile2 = new File("d:/test.txt");   
  • System.out.println("source file is exist? " + sourceFile.exists()   
  •     + ", source file => " + sourceFile);   
  • System.out.println(targetFile1 + " is exist? " + targetFile1.exists());   
  • System.out.println("rename to " + targetFile1 + " => "  
  •     + sourceFile.renameTo(targetFile1));   
  • System.out.println("source file is exist? " + sourceFile.exists()   
  •     + ", source file => " + sourceFile);   
  • System.out.println(targetFile2 + " is exist? " + targetFile2.exists());   
  • System.out.println("rename to " + targetFile2 + " => "  
  •     + sourceFile.renameTo(targetFile2));  



  • 注意看結(jié)果,從C盤到E盤失敗了,從C盤到D盤成功了。因?yàn)槲业碾娔XC、D兩個(gè)盤是NTFS格式的,而E盤是FAT32格式的。所以從C到E就是上面文章所說的"file systems"不一樣。從C到D由于同是NTFS分區(qū),所以不存在這個(gè)問題,當(dāng)然就成功了。

    果然是不能把File#renameTo(File)當(dāng)作move方法使用。

    可以考慮使用apache組織的commons-io包里面的FileUtils#copyFile(File,File)和FileUtils#copyFileToDirectory(File,File)方法實(shí)現(xiàn)copy的效果。至于刪除嘛,我想如果要求不是那么精確,可以調(diào)用File#deleteOnExit()方法,在虛擬機(jī)終止的時(shí)候,刪除掉這個(gè)目錄或文件。

    BTW:File是文件和目錄路徑名的抽象表示形式,所以有可能是目錄,千萬小心。
    下面我寫的一個(gè)實(shí)現(xiàn)方法

    /**
      * 使用FileChannel拷貝文件
      *
      * @param srcFile
      * @param destFile
      * @throws IOException
      */
     public static void copyUseChannel(File srcFile, File destFile)
       throws IOException {
      if ((!srcFile.exists()) || (srcFile.isDirectory())) {
       return;
      }

      if (!destFile.exists()) {
       createFile(destFile.getAbsolutePath());
      }

      FileChannel out = null;
      FileChannel in = null;
      try {
       out = new FileOutputStream(destFile).getChannel();
       in = new FileInputStream(srcFile).getChannel();
       ByteBuffer buffer = ByteBuffer.allocate(102400);
       int position = 0;
       int length = 0;
       while (true) {
        length = in.read(buffer, position);
        if (length <= 0) {
         break;
        }
        // System.out.println("after read:"+buffer);
        buffer.flip();
        // System.out.println("after flip:"+buffer);
        out.write(buffer, position);
        position += length;
        buffer.clear();
        // System.out.println("after clear:"+buffer);
       }

      } finally {
       if (out != null) {
        out.close();
       }
       if (in != null) {
        in.close();
       }
      }
     }

    posted @ 2008-10-27 10:15 bt下載 閱讀(1677) | 評(píng)論 (2)編輯 收藏

    CSDN首頁推薦了一篇文章,說兩位退休的美國(guó)大學(xué)教授上書反對(duì)將Java作為編程教學(xué)語言,對(duì)此我表示高度認(rèn)同。對(duì)于Java,我并不反感,而且相信它在工業(yè)應(yīng)用中的地位不可取代,但是,我一直反對(duì)將Java作為主要的編程教學(xué)語言,因?yàn)榻虒W(xué)語言承擔(dān)著與生產(chǎn)語言不同的任務(wù),它必須能夠幫助學(xué)生奠定堅(jiān)實(shí)的技術(shù)基礎(chǔ),塑造核心技術(shù)能力。在這方面,Java不能夠勝任。

    1990年代中期以前,美國(guó)的計(jì)算機(jī)編程入門教育以Pascal為主。我的一位美國(guó)程序員朋友至今還懷念他與Pascal為伴的高中年代。到了1990年代中后期,由于ANSI C語言“糾正”了早期C語言的一些不適合編程教學(xué)的問題,因此成為很多美國(guó)高中和大學(xué)編程入門課的教學(xué)語言。1998年,美國(guó)指導(dǎo)編程教學(xué)的一個(gè)協(xié)會(huì)推薦將C++作為入門教學(xué)語言,在當(dāng)時(shí)引起很大的反響,認(rèn)為是編程教育方面的一個(gè)重要進(jìn)步。但遺憾的是,C++非常復(fù)雜,而當(dāng)時(shí)C++語言的教育體系又非常不成熟,因此很多地方的教學(xué)方法不得當(dāng),把學(xué)生迅速拖入無邊無際的語言細(xì)節(jié)當(dāng)中,引起了學(xué)生痛苦的抱怨。大約經(jīng)過兩三年不成功的實(shí)踐之后,在本世紀(jì)初,美國(guó)計(jì)算機(jī)教育界普遍接受Java作為編程入門語言。此后在很短的時(shí)間里,Java迅速成為美國(guó)高中和大學(xué)里的首選編程教學(xué)語言,老師教得輕松,學(xué)生學(xué)得甜蜜,所以這個(gè)局面一直持續(xù)到現(xiàn)在。

    而在中國(guó),BASIC語言及其變體一直到1990年代中期都還是“算法語言”課程的主要教學(xué)內(nèi)容,充分折射出當(dāng)時(shí)中國(guó)計(jì)算機(jī)教學(xué)與工業(yè)應(yīng)用之間的脫節(jié)。只是到了1990年代后期,C語言才確立了在中國(guó)工科計(jì)算機(jī)編程入門教育中的主流地位。到現(xiàn)在為止,大部分工科學(xué)生都“必修”“C程序設(shè)計(jì)語言”這門課程。不過事實(shí)上,根據(jù)我的了解,這門課程的總體教學(xué)質(zhì)量相當(dāng)糟糕,大部分學(xué)生可以說是滿懷希望而來,兩手空空而去。在這種情況下,中國(guó)高校計(jì)算機(jī)編程入門教育已經(jīng)開始悄悄向Java過渡了。據(jù)我所知,有一些名校已經(jīng)開始將Java設(shè)為編程入門課程,并且認(rèn)為這是與國(guó)際接軌進(jìn)步標(biāo)志。

    在我的朋友圈子里,大多數(shù)真正的一線開發(fā)者和技術(shù)領(lǐng)導(dǎo)者,對(duì)于將Java作為入門教學(xué)語言的“發(fā)展方向”都持質(zhì)疑態(tài)度。他們中很多人目前主要的工作都集中在Java上,因此這種態(tài)度并非來自所謂語言宗教情緒,而是來自他們招聘和實(shí)際工作中的感受。他們發(fā)現(xiàn),只學(xué)習(xí)Java、C#、VB等“現(xiàn)代”編程語言的學(xué)生,精于拿來主義,長(zhǎng)于整合和快速開發(fā),思維活躍,生產(chǎn)效率高,讓他們來做直截了當(dāng)?shù)摹⒂姓驴裳摹⒎茄芯啃院头莿?chuàng)新性的工作比較合適,但是基礎(chǔ)不扎實(shí),對(duì)計(jì)算機(jī)系統(tǒng)的理解薄弱,處理細(xì)節(jié)和矛盾的能力不足,一旦他們熟悉的套路用不上,則缺少自主分析問題、解決問題的知識(shí)、能力和經(jīng)驗(yàn)。

    今天看到兩位教授的“上書”,才知道原來他們也有同感。只不過這兩位教授說的更直白,直接反對(duì)將Java作為入門編程語言,而是冒天下之大不韙,公然號(hào)召開歷史倒車,要求退回到C、C++、Lisp和Ada去。

    我是支持兩位教授的。我認(rèn)為,Java、C#、VB和其它虛擬機(jī)之上的語言都不適合作為專業(yè)程序員的入門教學(xué)語言。在中國(guó)還非常缺乏具有創(chuàng)新和獨(dú)立解決問題的高水平程序員的局面下,我們應(yīng)該認(rèn)真做好的事情是努力提高C/C++的教學(xué)質(zhì)量,而不是圖快活轉(zhuǎn)向Java。

    教學(xué)語言的選擇是至關(guān)重要的事情。作為大多數(shù)學(xué)生第一種需要認(rèn)真學(xué)習(xí)理解的編程語言,教學(xué)語言將會(huì)成為他們中間很多人的“編程母語”,深深地烙印在學(xué)生的思維方式中。這個(gè)編程母語要幫助學(xué)生破除計(jì)算機(jī)和軟件的神秘感,建立對(duì)于程序的基本認(rèn)識(shí)和對(duì)計(jì)算機(jī)模型的最初理解。在后續(xù)專業(yè)基礎(chǔ)課和專業(yè)課程的學(xué)習(xí)中,這門編程語言應(yīng)該作為主要工具貫穿始終,幫助學(xué)生認(rèn)識(shí)計(jì)算機(jī)系統(tǒng),掌握算法與數(shù)據(jù)結(jié)構(gòu)技能,熟悉操作系統(tǒng)概念,理解編譯原理知識(shí),理解軟件抽象及軟件設(shè)計(jì)的基本思想,完成一定量的課程及課外項(xiàng)目實(shí)踐,建立正確的軟件開發(fā)實(shí)踐習(xí)慣。不但如此,這種教學(xué)語言必須是工業(yè)界的主流語言,否則學(xué)生學(xué)非所用,學(xué)習(xí)動(dòng)力無法保證。

    按照這個(gè)標(biāo)準(zhǔn)來衡量,Java適合于作為主要的編程教學(xué)語言嗎?我不這么認(rèn)為。首先,我承認(rèn)Java在教學(xué)上有一些優(yōu)勢(shì),比如其開發(fā)環(huán)境和工具支持非常成熟,有助于培養(yǎng)學(xué)生正確的編程習(xí)慣;Java是當(dāng)今第一工業(yè)主流語言,標(biāo)準(zhǔn)類庫非常全面,可以迅速地開發(fā)具有實(shí)際用途的程序,有助于激發(fā)和保持學(xué)生的興趣;而在數(shù)據(jù)結(jié)構(gòu)、算法、編譯原理的教學(xué)方面,Java也毫不落于下風(fēng),在軟件抽象設(shè)計(jì)(面向?qū)ο螅┓矫妫琂ava還有著明顯的優(yōu)勢(shì);特別是在并行編程的教學(xué)方面,Java 1.5 concurrency包提供的優(yōu)勢(shì)是壓倒性的。盡管有如上這些優(yōu)勢(shì),但Java作為教學(xué)語言存在著一個(gè)致命的缺陷,即它是一個(gè)虛擬機(jī)語言,這一點(diǎn)就足以把它從教學(xué)語言的名單上去掉。作為一個(gè)虛擬機(jī)語言,Java對(duì)開發(fā)者隔絕了下層的真實(shí)系統(tǒng),從而構(gòu)造了一個(gè)近乎完美的環(huán)境,在這個(gè)環(huán)境里,世界上只有一種機(jī)器,一個(gè)操作系統(tǒng),內(nèi)存是無限的,所有的機(jī)器都具有相同的字節(jié)順序和一致的類型約定,為了設(shè)計(jì)的優(yōu)美而犧牲速度永遠(yuǎn)是正義行為,從反射到運(yùn)行時(shí)自動(dòng)加載,從完備的容器類到統(tǒng)一字符編碼,一大堆漂亮的功能都可以不費(fèi)吹灰之力唾手而得。要是這個(gè)世界上每臺(tái)計(jì)算機(jī)都是一個(gè)Java機(jī)器,每項(xiàng)編程任務(wù)都可以在這樣一個(gè)近乎完美的環(huán)境中開發(fā),那毫無以為,Java是最合適的編程教學(xué)語言。但是事實(shí)上呢?這樣一個(gè)完美的環(huán)境是Java力量的源泉,但這卻不是真實(shí)的世界。在真實(shí)世界里,我們可能面對(duì)非常原始的環(huán)境,苛刻的運(yùn)行時(shí)限制,復(fù)雜多變的系統(tǒng)環(huán)境,令人窒息的細(xì)節(jié)魔鬼,要對(duì)付這些東西,需要開發(fā)者具有在應(yīng)對(duì)復(fù)雜性,自己構(gòu)造環(huán)境,在諸多限制條件下尋找解決方案的能力。而這種能力,被無數(shù)人無數(shù)次地證明是軟件開發(fā)、特別是軟件創(chuàng)新的核心能力。把Java作為教學(xué)語言,恰恰會(huì)導(dǎo)致這種核心能力的缺失。除此之外,如果耐心觀察的話,不難發(fā)現(xiàn),幾乎在任何軟件領(lǐng)域里的創(chuàng)新性成果都首先是由C/C++語言實(shí)現(xiàn)的,原因很簡(jiǎn)單,Java是站在C/C++基礎(chǔ)之上的,只有C/C++先把大路趟開,Java才能夠順勢(shì)而上。

    相反,盡管C/C++語言作為教學(xué)語言有很多的不足,比如不同環(huán)境下開發(fā)模式差異大,細(xì)節(jié)繁多,開發(fā)效率低,容易犯錯(cuò),測(cè)試和調(diào)試?yán)щy,學(xué)習(xí)者難以保持動(dòng)力,等等,但是這些問題都可以解決。而C/C++的關(guān)鍵優(yōu)點(diǎn),是能夠讓學(xué)習(xí)者在真實(shí)的計(jì)算機(jī)抽象上、在大量的細(xì)節(jié)和矛盾中學(xué)會(huì)思考,學(xué)會(huì)解決問題,學(xué)會(huì)了解真實(shí)的系統(tǒng),知輕重,明生死,從而建立核心能力。掌握了C/C++ bt語言,再去學(xué)習(xí)和理解Java、C#、Python、Ruby和其它語言,就比較容易達(dá)到更高的境界。反之,如果習(xí)慣了舒舒服服躺在完美世界里當(dāng)闊少,那就很難有勇氣面對(duì)真實(shí)的世界。當(dāng)然,很多開發(fā)者認(rèn)為,現(xiàn)在更重要的能力是理解業(yè)務(wù)、整合現(xiàn)有資源的能力,而不是處理底層細(xì)節(jié)的技術(shù)。這種說法放在個(gè)人身上沒有問題,但是不能成為整個(gè)編程教育的指導(dǎo)思想。我們需要各個(gè)層面上的人才,精通業(yè)務(wù)和設(shè)計(jì)的架構(gòu)師固然很重要,但能夠在底層作出創(chuàng)新成果的編程高手實(shí)際上更為稀缺和珍貴,很多時(shí)候也能夠創(chuàng)造更大的價(jià)值。而且,更重要的是,一個(gè)精通系統(tǒng)知識(shí)的開發(fā)者在往上走的時(shí)候不會(huì)遇到大的障礙,而一個(gè)只知道拼裝組合的“高級(jí)設(shè)計(jì)師”,往往連往下看的勇氣都沒有。

    Java的另外一個(gè)問題,是其所倡導(dǎo)的繁瑣設(shè)計(jì)風(fēng)格,一個(gè)對(duì)象套一個(gè)對(duì)象,一個(gè)對(duì)象疊一個(gè)對(duì)象,概念之間彼此橫七豎八地互相依賴,人為制造出一大堆貌似精美、實(shí)則累贅的所謂設(shè)計(jì)。這個(gè)問題我已經(jīng)批評(píng)過多次,并且相信這股歪風(fēng)一定會(huì)最終被人們拋棄,Java最終會(huì)歸于質(zhì)樸。但是在這一天到來之前,Java對(duì)于初學(xué)者來說,很可能蒙住他們的雙眼,使他們看不到軟件設(shè)計(jì)中最可貴的簡(jiǎn)單性和優(yōu)美的統(tǒng)一,體會(huì)不到數(shù)據(jù)和程序的統(tǒng)一。在這一點(diǎn)上,C表現(xiàn)的非常好,而C++如果教學(xué)得體,可以做的更好。

    當(dāng)然,這并不是為現(xiàn)在的C/C++教學(xué)辯護(hù)。恰恰相反,從我了解的情況來看,目前普通高校的C/C++教學(xué)質(zhì)量非常令人擔(dān)憂。學(xué)生學(xué)不會(huì),而且越學(xué)越?jīng)]有興趣,老師則感到教起來很棘手,迫于現(xiàn)實(shí)情況往往選擇敷衍了事。反而是教Java,無論如何學(xué)生還能學(xué)到一點(diǎn)東西,對(duì)就業(yè)也有直接的幫助。至于學(xué)生的核心能力確實(shí),發(fā)展后勁不足等問題,就讓他們?cè)诂F(xiàn)實(shí)工作中自己解決吧。坦率地說,這種想法也很有道理。不過,從教學(xué)角度來說,我認(rèn)為老師們還是應(yīng)該積極考慮如何提高C/C++的教學(xué)質(zhì)量。畢竟學(xué)生階段是十分寶貴的,基礎(chǔ)不在這個(gè)時(shí)期夯實(shí),將來想彌補(bǔ),就算不是完全不可能,也將付出十倍的代價(jià)。本著對(duì)學(xué)生職業(yè)生涯的負(fù)責(zé)態(tài)度,還是應(yīng)該幫助學(xué)生達(dá)到這個(gè)階段應(yīng)該達(dá)到的目標(biāo)。在兩位教授的公開信里,也充分表達(dá)出這個(gè)意思。

    我贊成的編程教育過程,應(yīng)當(dāng)是以C/C++(基本上是C)為主線,貫穿起算法、數(shù)據(jù)結(jié)構(gòu)、系統(tǒng)原理、編譯和數(shù)據(jù)處理、軟件設(shè)計(jì)和組件技術(shù)等關(guān)鍵知識(shí)領(lǐng)域,讓學(xué)生能夠從根本上理解現(xiàn)代軟件系統(tǒng)的原理和構(gòu)造,并通過有效的練習(xí)建立正確的軟件設(shè)計(jì)觀念和良好的工程實(shí)踐習(xí)慣。在這個(gè)基礎(chǔ)上,無論將來是深入學(xué)習(xí)C++,還是進(jìn)入Java的繁榮世界,或者擁抱Python、Ruby,甚至于走向Web開發(fā),都會(huì)心領(lǐng)神會(huì),勢(shì)如破竹。

    posted @ 2008-10-14 19:38 bt下載| 編輯 收藏

    第1章基礎(chǔ)知識(shí)

    1.1. 單鑰密碼體制

    單鑰密碼體制是一種傳統(tǒng)的加密算法,是指信息的發(fā)送方和接收方共同使用同一把密鑰進(jìn)行加解密。

    通常,使用的加密算法比較簡(jiǎn)便高效,密鑰簡(jiǎn)短,加解密速度快,破譯極其困難。但是加密的安全性依靠密鑰保管的安全性,在公開的計(jì)算機(jī)網(wǎng)絡(luò)上安全地傳送和保管密鑰是一個(gè)嚴(yán)峻的問題,并且如果在多用戶的情況下密鑰的保管安全性也是一個(gè)問題。

    單鑰密碼體制的代表是美國(guó)的DES

    1.2. 消息摘要

    一個(gè)消息摘要就是一個(gè)數(shù)據(jù)塊的數(shù)字指紋。即對(duì)一個(gè)任意長(zhǎng)度的一個(gè)數(shù)據(jù)塊進(jìn)行計(jì)算,產(chǎn)生一個(gè)唯一指印(對(duì)于SHA1是產(chǎn)生一個(gè)20字節(jié)的二進(jìn)制數(shù)組)。

    消息摘要有兩個(gè)基本屬性:

    • 兩個(gè)不同的報(bào)文難以生成相同的摘要
    • 難以對(duì)指定的摘要生成一個(gè)報(bào)文,而由該報(bào)文反推算出該指定的摘要

    代表:美國(guó)國(guó)家標(biāo)準(zhǔn)技術(shù)研究所的SHA1和麻省理工學(xué)院Ronald Rivest提出的MD5

    1.3. Diffie-Hellman密鑰一致協(xié)議

    密鑰一致協(xié)議是由公開密鑰密碼體制的奠基人Diffie和Hellman所提出的一種思想。

    先決條件,允許兩名用戶在公開媒體上交換信息以生成"一致"的,可以共享的密鑰

    代表:指數(shù)密鑰一致協(xié)議(Exponential Key Agreement Protocol)

    1.4. 非對(duì)稱算法與公鑰體系

    1976年,Dittie和Hellman為解決密鑰管理問題,在他們的奠基性的工作"密碼學(xué)的新方向"一文中,提出一種密鑰交換協(xié)議,允許在不安全的媒體上通過通訊雙方交換信息,安全地傳送秘密密鑰。在此新思想的基礎(chǔ)上,很快出現(xiàn)了非對(duì)稱密鑰密碼體制,即公鑰密碼體制。在公鑰體制中,加密密鑰不同于解密密鑰,加密密鑰公之于眾,誰都可以使用;解密密鑰只有解密人自己知道。它們分別稱為公開密鑰(Public key)和秘密密鑰(Private key)。

    迄今為止的所有公鑰密碼體系中,RSA系統(tǒng)是最著名、最多使用的一種。RSA公開密鑰密碼系統(tǒng)是由R.Rivest、A.Shamir和L.Adleman俊教授于1977年提出的。RSA的取名就是來自于這三位發(fā)明者的姓的第一個(gè)字母

    1.5. 數(shù)字簽名

    所謂數(shù)字簽名就是信息發(fā)送者用其私鑰對(duì)從所傳報(bào)文中提取出的特征數(shù)據(jù)(或稱數(shù)字指紋)進(jìn)行RSA算法操作,以保證發(fā)信人無法抵賴曾發(fā)過該信息(即不可抵賴性),同時(shí)也確保信息報(bào)文在經(jīng)簽名后末被篡改(即完整性)。當(dāng)信息接收者收到報(bào)文后,就可以用發(fā)送者的公鑰對(duì)數(shù)字簽名進(jìn)行驗(yàn)證。 

    在數(shù)字簽名中有重要作用的數(shù)字指紋是通過一類特殊的散列函數(shù)(HASH函數(shù))生成的,對(duì)這些HASH函數(shù)的特殊要求是:

    1. 接受的輸入報(bào)文數(shù)據(jù)沒有長(zhǎng)度限制;
    2. 對(duì)任何輸入報(bào)文數(shù)據(jù)生成固定長(zhǎng)度的摘要(數(shù)字指紋)輸出
    3. 從報(bào)文能方便地算出摘要;
    4. 難以對(duì)指定的摘要生成一個(gè)報(bào)文,而由該報(bào)文反推算出該指定的摘要;
    5. 兩個(gè)不同的報(bào)文難以生成相同的摘要

    代表:DSA





    回頁首


    第2章在JAVA中的實(shí)現(xiàn)

    2.1. 相關(guān)

    Diffie-Hellman密鑰一致協(xié)議和DES程序需要JCE工具庫的支持,可以到 http://java.sun.com/security/index.html  或是www.bt285.cn 下載JCE,并進(jìn)行安裝。簡(jiǎn)易安裝把 jce1.2.1\lib 下的所有內(nèi)容復(fù)制到 %java_home%\lib\ext下,如果沒有ext目錄自行建立,再把jce1_2_1.jar和sunjce_provider.jar添加到CLASSPATH內(nèi),更詳細(xì)說明請(qǐng)看相應(yīng)用戶手冊(cè)

    2.2. 消息摘要MD5和SHA的使用

    使用方法:

    首先用生成一個(gè)MessageDigest類,確定計(jì)算方法

    java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");

    添加要進(jìn)行計(jì)算摘要的信息

    alga.update(myinfo.getBytes());

    計(jì)算出摘要

    byte[] digesta=alga.digest();

    發(fā)送給其他人你的信息和摘要

    其他人用相同的方法初始化,添加信息,最后進(jìn)行比較摘要是否相同

    algb.isEqual(digesta,algb.digest())

    相關(guān)AIP

    java.security.MessageDigest 類

    static getInstance(String algorithm)

    返回一個(gè)MessageDigest對(duì)象,它實(shí)現(xiàn)指定的算法

    參數(shù):算法名,如 SHA-1 或MD5

    void update (byte input)

    void update (byte[] input)

    void update(byte[] input, int offset, int len)

    添加要進(jìn)行計(jì)算摘要的信息

    byte[] digest()

    完成計(jì)算,返回計(jì)算得到的摘要(對(duì)于MD5是16位,SHA是20位)

    void reset()

    復(fù)位

    static boolean isEqual(byte[] digesta, byte[] digestb)

    比效兩個(gè)摘要是否相同

    代碼:

    import java.security.*;
                public class myDigest {
                public static void main(String[] args)  {
                myDigest my=new myDigest();
                my.testDigest();
                }
                public void testDigest()
                {
                try {
                String myinfo="我的測(cè)試信息";
                //java.security.MessageDigest alg=java.security.MessageDigest.getInstance("MD5");
                java.security.MessageDigest alga=java.security.MessageDigest.getInstance("SHA-1");
                alga.update(myinfo.getBytes());
                byte[] digesta=alga.digest();
                System.out.println("本信息摘要是:"+byte2hex(digesta));
                //通過某中方式傳給其他人你的信息(myinfo)和摘要(digesta) 對(duì)方可以判斷是否更改或傳輸正常
                java.security.MessageDigest algb=java.security.MessageDigest.getInstance("SHA-1");
                algb.update(myinfo.getBytes());
                if (algb.isEqual(digesta,algb.digest())) {
                System.out.println("信息檢查正常");
                }
                else
                {
                System.out.println("摘要不相同");
                }
                }
                catch (java.security.NoSuchAlgorithmException ex) {
                System.out.println("非法摘要算法");
                }
                }
                public String byte2hex(byte[] b) //二行制轉(zhuǎn)字符串
                {
                String hs="";
                String stmp="";
                for (int n=0;n<b.length;n++)
                {
                stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                if (stmp.length()==1) hs=hs+"0"+stmp;
                else hs=hs+stmp;
                if (n<b.length-1)  hs=hs+":";
                }
                return hs.toUpperCase();
                }
                }

    2.3. 數(shù)字簽名DSA

    1. 對(duì)于一個(gè)用戶來講首先要生成他的密鑰對(duì),并且分別保存

      生成一個(gè)KeyPairGenerator實(shí)例

         java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");
                          如果設(shè)定隨機(jī)產(chǎn)生器就用如相代碼初始化
                      SecureRandom secrand=new SecureRandom();
                      secrand.setSeed("tttt".getBytes()); //初始化隨機(jī)產(chǎn)生器
                      keygen.initialize(512,secrand);     //初始化密鑰生成器
                      否則
                      keygen.initialize(512);
                      生成密鑰公鑰pubkey和私鑰prikey
                      KeyPair keys=keygen.generateKeyPair(); //生成密鑰組
                      PublicKey pubkey=keys.getPublic();
                      PrivateKey prikey=keys.getPrivate();
                      分別保存在myprikey.dat和mypubkey.dat中,以便下次不在生成
                      (生成密鑰對(duì)的時(shí)間比較長(zhǎng)
                      java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));
                           out.writeObject(prikey);
                      out.close();
                      out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));
                           out.writeObject(pubkey);
                      out.close();
                      


    2. 用他私人密鑰(prikey)對(duì)他所確認(rèn)的信息(info)進(jìn)行數(shù)字簽名產(chǎn)生一個(gè)簽名數(shù)組

      從文件中讀入私人密鑰(prikey)

         java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));
                          PrivateKey myprikey=(PrivateKey)in.readObject();
                      in.close();
                      初始一個(gè)Signature對(duì)象,并用私鑰對(duì)信息簽名
                      java.security.Signature signet=java.security.Signature.getInstance("DSA");
                      signet.initSign(myprikey);
                      signet.update(myinfo.getBytes());
                      byte[] signed=signet.sign();
                      把信息和簽名保存在一個(gè)文件中(myinfo.dat)
                      java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));
                            out.writeObject(myinfo);
                      out.writeObject(signed);
                      out.close();
                      把他的公鑰的信息及簽名發(fā)給其它用戶
                      


    3. 其他用戶用他的公共密鑰(pubkey)和簽名(signed)和信息(info)進(jìn)行驗(yàn)證是否由他簽名的信息

      讀入公鑰
      java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
      PublicKey pubkey=(PublicKey)in.readObject();
      in.close();

      讀入簽名和信息
      in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
      String info=(String)in.readObject();
      byte[] signed=(byte[])in.readObject();
      in.close();

      初始一個(gè)Signature對(duì)象,并用公鑰和簽名進(jìn)行驗(yàn)證
      java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
      signetcheck.initVerify(pubkey);
      signetcheck.update(info.getBytes());
      if (signetcheck.verify(signed)) { System.out.println("簽名正常");}

      對(duì)于密鑰的保存本文是用對(duì)象流的方式保存和傳送的,也可可以用編碼的方式保存.注意要
      import java.security.spec.*
      import java.security.*

      具休說明如下

      • public key是用X.509編碼的,例碼如下:
          byte[] bobEncodedPubKey=mypublic.getEncoded(); //生成編碼
                            //傳送二進(jìn)制編碼
                            //以下代碼轉(zhuǎn)換編碼為相應(yīng)key對(duì)象
                            X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
                            KeyFactory keyFactory = KeyFactory.getInstance("DSA");
                            PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
                            


      • 對(duì)于Private key是用PKCS#8編碼,例碼如下:
         byte[] bPKCS=myprikey.getEncoded();
                            //傳送二進(jìn)制編碼
                            //以下代碼轉(zhuǎn)換編碼為相應(yīng)key對(duì)象
                            PKCS8EncodedKeySpec priPKCS8=new PKCS8EncodedKeySpec(bPKCS);
                            KeyFactory keyf=KeyFactory.getInstance("DSA");
                            PrivateKey otherprikey=keyf.generatePrivate(priPKCS8);
                            


    4. 常用API

      java.security.KeyPairGenerator 密鑰生成器類
      public static KeyPairGenerator getInstance(String algorithm) throws NoSuchAlgorithmException
      以指定的算法返回一個(gè)KeyPairGenerator 對(duì)象
      參數(shù): algorithm 算法名.如:"DSA","RSA"

      public void initialize(int keysize)

      以指定的長(zhǎng)度初始化KeyPairGenerator對(duì)象,如果沒有初始化系統(tǒng)以1024長(zhǎng)度默認(rèn)設(shè)置

      參數(shù):keysize 算法位長(zhǎng).其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)

      public void initialize(int keysize, SecureRandom random)
      以指定的長(zhǎng)度初始化和隨機(jī)發(fā)生器初始化KeyPairGenerator對(duì)象
      參數(shù):keysize 算法位長(zhǎng).其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)
      random 一個(gè)隨機(jī)位的來源(對(duì)于initialize(int keysize)使用了默認(rèn)隨機(jī)器

      public abstract KeyPair generateKeyPair()
      產(chǎn)生新密鑰對(duì)

      java.security.KeyPair 密鑰對(duì)類
      public PrivateKey getPrivate()
      返回私鑰

      public PublicKey getPublic()
      返回公鑰

      java.security.Signature 簽名類
      public static Signature getInstance(String algorithm) throws NoSuchAlgorithmException
      返回一個(gè)指定算法的Signature對(duì)象
      參數(shù) algorithm 如:"DSA"

      public final void initSign(PrivateKey privateKey)
      throws InvalidKeyException
      用指定的私鑰初始化
      參數(shù):privateKey 所進(jìn)行簽名時(shí)用的私鑰

      public final void update(byte data)
      throws SignatureException
      public final void update(byte[] data)
      throws SignatureException
      public final void update(byte[] data, int off, int len)
      throws SignatureException
      添加要簽名的信息

      public final byte[] sign()
      throws SignatureException
      返回簽名的數(shù)組,前提是initSign和update

      public final void initVerify(PublicKey publicKey)
      throws InvalidKeyException
      用指定的公鑰初始化
      參數(shù):publicKey 驗(yàn)證時(shí)用的公鑰

      public final boolean verify(byte[] signature)
      throws SignatureException
      驗(yàn)證簽名是否有效,前提是已經(jīng)initVerify初始化
      參數(shù): signature 簽名數(shù)組

       */
                      import java.security.*;
                      import java.security.spec.*;
                      public class testdsa {
                      public static void main(String[] args) throws java.security.NoSuchAlgorithmException,java.lang.Exception {
                              testdsa my=new testdsa();
                      my.run();
                      }
                      public void run()
                      {
                      //數(shù)字簽名生成密鑰
                      //第一步生成密鑰對(duì),如果已經(jīng)生成過,本過程就可以跳過,對(duì)用戶來講myprikey.dat要保存在本地
                      //而mypubkey.dat給發(fā)布給其它用戶
                      if ((new java.io.File("myprikey.dat")).exists()==false) {
                      if (generatekey()==false) {
                      System.out.println("生成密鑰對(duì)敗");
                      return;
                      };
                      }
                      //第二步,此用戶
                      //從文件中讀入私鑰,對(duì)一個(gè)字符串進(jìn)行簽名后保存在一個(gè)文件(myinfo.dat)中
                      //并且再把myinfo.dat發(fā)送出去
                      //為了方便數(shù)字簽名也放進(jìn)了myifno.dat文件中,當(dāng)然也可分別發(fā)送
                      try {
                      java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("myprikey.dat"));
                        PrivateKey myprikey=(PrivateKey)in.readObject();
                      in.close();
                      // java.security.spec.X509EncodedKeySpec pubX509=new java.security.spec.X509EncodedKeySpec(bX509);
                       //java.security.spec.X509EncodedKeySpec pubkeyEncode=java.security.spec.X509EncodedKeySpec
                        String myinfo="這是我的信息";    //要簽名的信息
                      //用私鑰對(duì)信息生成數(shù)字簽名
                      java.security.Signature signet=java.security.Signature.getInstance("DSA");
                      signet.initSign(myprikey);
                      signet.update(myinfo.getBytes());
                      byte[] signed=signet.sign();  //對(duì)信息的數(shù)字簽名
                      System.out.println("signed(簽名內(nèi)容)="+byte2hex(signed));
                      //把信息和數(shù)字簽名保存在一個(gè)文件中
                      java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myinfo.dat"));
                        out.writeObject(myinfo);
                      out.writeObject(signed);
                      out.close();
                      System.out.println("簽名并生成文件成功");
                      }
                      catch (java.lang.Exception e) {
                      e.printStackTrace();
                      System.out.println("簽名并生成文件失敗");
                      };
                      //第三步
                      //其他人通過公共方式得到此戶的公鑰和文件
                      //其他人用此戶的公鑰,對(duì)文件進(jìn)行檢查,如果成功說明是此用戶發(fā)布的信息.
                      //
                      try {
                      java.io.ObjectInputStream in=new java.io.ObjectInputStream(new java.io.FileInputStream("mypubkey.dat"));
                         PublicKey pubkey=(PublicKey)in.readObject();
                      in.close();
                      System.out.println(pubkey.getFormat());
                      in=new java.io.ObjectInputStream(new java.io.FileInputStream("myinfo.dat"));
                      String info=(String)in.readObject();
                      byte[] signed=(byte[])in.readObject();
                      in.close();
                      java.security.Signature signetcheck=java.security.Signature.getInstance("DSA");
                      signetcheck.initVerify(pubkey);
                      signetcheck.update(info.getBytes());
                      if (signetcheck.verify(signed)) {
                      System.out.println("info="+info);
                      System.out.println("簽名正常");
                      }
                      else  System.out.println("非簽名正常");
                      }
                      catch (java.lang.Exception e) {e.printStackTrace();};
                      }
                      //生成一對(duì)文件myprikey.dat和mypubkey.dat---私鑰和公鑰,
                      //公鑰要用戶發(fā)送(文件,網(wǎng)絡(luò)等方法)給其它用戶,私鑰保存在本地
                      public boolean generatekey()
                      {
                      try {
                      java.security.KeyPairGenerator  keygen=java.security.KeyPairGenerator.getInstance("DSA");
                       // SecureRandom secrand=new SecureRandom();
                      // secrand.setSeed("tttt".getBytes()); //初始化隨機(jī)產(chǎn)生器
                      // keygen.initialize(576,secrand);     //初始化密鑰生成器
                      keygen.initialize(512);
                      KeyPair keys=keygen.genKeyPair();
                      //  KeyPair keys=keygen.generateKeyPair(); //生成密鑰組
                      PublicKey pubkey=keys.getPublic();
                      PrivateKey prikey=keys.getPrivate();
                      java.io.ObjectOutputStream out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("myprikey.dat"));
                        out.writeObject(prikey);
                      out.close();
                      System.out.println("寫入對(duì)象 prikeys ok");
                      out=new java.io.ObjectOutputStream(new java.io.FileOutputStream("mypubkey.dat"));
                      out.writeObject(pubkey);
                      out.close();
                      System.out.println("寫入對(duì)象 pubkeys ok");
                      System.out.println("生成密鑰對(duì)成功");
                      return true;
                      }
                      catch (java.lang.Exception e) {
                      e.printStackTrace();
                      System.out.println("生成密鑰對(duì)失敗");
                      return false;
                      };
                      }
                      public String byte2hex(byte[] b)
                      {
                      String hs="";
                      String stmp="";
                      for (int n=0;n<b.length;n++)
                      {
                      stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                      if (stmp.length()==1) hs=hs+"0"+stmp;
                      else hs=hs+stmp;
                      if (n<b.length-1)  hs=hs+":";
                      }
                      return hs.toUpperCase();
                      }
                      }


    2.4. DESede/DES對(duì)稱算法

    首先生成密鑰,并保存(這里并沒的保存的代碼,可參考DSA中的方法)

    KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);

    SecretKey deskey = keygen.generateKey();

    用密鑰加密明文(myinfo),生成密文(cipherByte)

    Cipher c1 = Cipher.getInstance(Algorithm);

    c1.init(Cipher.ENCRYPT_MODE,deskey);

    byte[] cipherByte=c1.doFinal(myinfo.getBytes());

    傳送密文和密鑰,本文沒有相應(yīng)代碼可參考DSA

    .............

    用密鑰解密密文

    c1 = Cipher.getInstance(Algorithm);

    c1.init(Cipher.DECRYPT_MODE,deskey);

    byte[] clearByte=c1.doFinal(cipherByte);

    相對(duì)來說對(duì)稱密鑰的使用是很簡(jiǎn)單的,對(duì)于JCE來講支技DES,DESede,Blowfish三種加密術(shù)

    對(duì)于密鑰的保存各傳送可使用對(duì)象流或者用二進(jìn)制編碼,相關(guān)參考代碼如下

       SecretKey deskey = keygen.generateKey();
                byte[] desEncode=deskey.getEncoded();
                javax.crypto.spec.SecretKeySpec destmp=new javax.crypto.spec.SecretKeySpec(desEncode,Algorithm);
                   SecretKey mydeskey=destmp;

    相關(guān)API

    KeyGenerator 在DSA中已經(jīng)說明,在添加JCE后在instance進(jìn)可以如下參數(shù)

    DES,DESede,Blowfish,HmacMD5,HmacSHA1

    javax.crypto.Cipher 加/解密器

    public static final Cipher getInstance(java.lang.String transformation)
                throws java.security.NoSuchAlgorithmException,
                NoSuchPaddingException

    返回一個(gè)指定方法的Cipher對(duì)象

    參數(shù):transformation 方法名(可用 DES,DESede,Blowfish)

    public final void init(int opmode, java.security.Key key)
    throws java.security.InvalidKeyException

    用指定的密鑰和模式初始化Cipher對(duì)象

    參數(shù):opmode 方式(ENCRYPT_MODE, DECRYPT_MODE, WRAP_MODE,UNWRAP_MODE)

    key 密鑰

    public final byte[] doFinal(byte[] input)
                throws java.lang.IllegalStateException,
                IllegalBlockSizeException,
                BadPaddingException
                

    對(duì)input內(nèi)的串,進(jìn)行編碼處理,返回處理后二進(jìn)制串,是返回解密文還是加解文由init時(shí)的opmode決定

    注意:本方法的執(zhí)行前如果有update,是對(duì)updat和本次input全部處理,否則是本inout的內(nèi)容

    /*
                安全程序 DESede/DES測(cè)試
                */
                import java.security.*;
                import javax.crypto.*;
                public class testdes {
                public static void main(String[] args){
                testdes my=new testdes();
                my.run();
                }
                public  void run() {
                //添加新安全算法,如果用JCE就要把它添加進(jìn)去
                Security.addProvider(new com.sun.crypto.provider.SunJCE());
                String Algorithm="DES"; //定義 加密算法,可用 DES,DESede,Blowfish
                String myinfo="要加密的信息";
                try {
                //生成密鑰
                KeyGenerator keygen = KeyGenerator.getInstance(Algorithm);
                SecretKey deskey = keygen.generateKey();
                //加密
                System.out.println("加密前的二進(jìn)串:"+byte2hex(myinfo.getBytes()));
                System.out.println("加密前的信息:"+myinfo);
                Cipher c1 = Cipher.getInstance(Algorithm);
                c1.init(Cipher.ENCRYPT_MODE,deskey);
                byte[] cipherByte=c1.doFinal(myinfo.getBytes());
                System.out.println("加密后的二進(jìn)串:"+byte2hex(cipherByte));
                //解密
                c1 = Cipher.getInstance(Algorithm);
                c1.init(Cipher.DECRYPT_MODE,deskey);
                byte[] clearByte=c1.doFinal(cipherByte);
                System.out.println("解密后的二進(jìn)串:"+byte2hex(clearByte));
                System.out.println("解密后的信息:"+(new String(clearByte)));
                }
                catch (java.security.NoSuchAlgorithmException e1) {e1.printStackTrace();}
                catch (javax.crypto.NoSuchPaddingException e2) {e2.printStackTrace();}
                catch (java.lang.Exception e3) {e3.printStackTrace();}
                }
                public String byte2hex(byte[] b) //二行制轉(zhuǎn)字符串
                {
                String hs="";
                String stmp="";
                for (int n=0;n<b.length;n++)
                {
                stmp=(java.lang.Integer.toHexString(b[n] & 0XFF));
                if (stmp.length()==1) hs=hs+"0"+stmp;
                else hs=hs+stmp;
                if (n<b.length-1)  hs=hs+":";
                }
                return hs.toUpperCase();
                }
                }


    2.5. Diffie-Hellman密鑰一致協(xié)議

    公開密鑰密碼體制的奠基人Diffie和Hellman所提出的 "指數(shù)密鑰一致協(xié)議"(Exponential Key Agreement Protocol),該協(xié)議不要求別的安全性先決條件,允許兩名用戶在公開媒體上交換信息以生成"一致"的,可以共享的密鑰。在JCE的中實(shí)現(xiàn)用戶alice生成DH類型的密鑰對(duì),如果長(zhǎng)度用1024生成的時(shí)間請(qǐng),推薦第一次生成后保存DHParameterSpec,以便下次使用直接初始化.使其速度加快

    System.out.println("ALICE: 產(chǎn)生 DH 對(duì) ...");
                KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");
                aliceKpairGen.initialize(512);
                KeyPair aliceKpair = aliceKpairGen.generateKeyPair();

    alice生成公鑰發(fā)送組bob

    byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded();

    bob從alice發(fā)送來的公鑰中讀出DH密鑰對(duì)的初始參數(shù)生成bob的DH密鑰對(duì)

    注意這一步一定要做,要保證每個(gè)用戶用相同的初始參數(shù)生成的

       DHParameterSpec dhParamSpec = ((DHPublicKey)alicePubKey).getParams();
                KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
                bobKpairGen.initialize(dhParamSpec);
                KeyPair bobKpair = bobKpairGen.generateKeyPair();

    bob根據(jù)alice的公鑰生成本地的DES密鑰

       KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
                bobKeyAgree.init(bobKpair.getPrivate());
                bobKeyAgree.doPhase(alicePubKey, true);
                SecretKey bobDesKey = bobKeyAgree.generateSecret("DES");

    bob已經(jīng)生成了他的DES密鑰,他現(xiàn)把他的公鑰發(fā)給alice,

          byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded();

    alice根據(jù)bob的公鑰生成本地的DES密鑰

           ,,,,,,解碼
                KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
                aliceKeyAgree.init(aliceKpair.getPrivate());
                aliceKeyAgree.doPhase(bobPubKey, true);
                SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES");

    bob和alice能過這個(gè)過程就生成了相同的DES密鑰,在這種基礎(chǔ)就可進(jìn)行安全能信

    常用API

    java.security.KeyPairGenerator 密鑰生成器類
    public static KeyPairGenerator getInstance(String algorithm)
    throws NoSuchAlgorithmException
    以指定的算法返回一個(gè)KeyPairGenerator 對(duì)象
    參數(shù): algorithm 算法名.如:原來是DSA,現(xiàn)在添加了 DiffieHellman(DH)

    public void initialize(int keysize)
    以指定的長(zhǎng)度初始化KeyPairGenerator對(duì)象,如果沒有初始化系統(tǒng)以1024長(zhǎng)度默認(rèn)設(shè)置
    參數(shù):keysize 算法位長(zhǎng).其范圍必須在 512 到 1024 之間,且必須為 64 的倍數(shù)
    注意:如果用1024生長(zhǎng)的時(shí)間很長(zhǎng),最好生成一次后就保存,下次就不用生成了

    public void initialize(AlgorithmParameterSpec params)
    throws InvalidAlgorithmParameterException
    以指定參數(shù)初始化

    javax.crypto.interfaces.DHPublicKey
    public DHParameterSpec getParams()
    返回
    java.security.KeyFactory

    public static KeyFactory getInstance(String algorithm)
    throws NoSuchAlgorithmException
    以指定的算法返回一個(gè)KeyFactory
    參數(shù): algorithm 算法名:DSH,DH

    public final PublicKey generatePublic(KeySpec keySpec)
    throws InvalidKeySpecException
    根據(jù)指定的key說明,返回一個(gè)PublicKey對(duì)象

    java.security.spec.X509EncodedKeySpec
    public X509EncodedKeySpec(byte[] encodedKey)
    根據(jù)指定的二進(jìn)制編碼的字串生成一個(gè)key的說明
    參數(shù):encodedKey 二進(jìn)制編碼的字串(一般能過PublicKey.getEncoded()生成)
    javax.crypto.KeyAgreement 密碼一至類

    public static final KeyAgreement getInstance(java.lang.String algorithm)
    throws java.security.NoSuchAlgorithmException
    返回一個(gè)指定算法的KeyAgreement對(duì)象
    參數(shù):algorithm 算法名,現(xiàn)在只能是DiffieHellman(DH)

    public final void init(java.security.Key key)
    throws java.security.InvalidKeyException
    用指定的私鑰初始化
    參數(shù):key 一個(gè)私鑰

    public final java.security.Key doPhase(java.security.Key key,
    boolean lastPhase)
    throws java.security.InvalidKeyException,
    java.lang.IllegalStateException
    用指定的公鑰進(jìn)行定位,lastPhase確定這是否是最后一個(gè)公鑰,對(duì)于兩個(gè)用戶的
    情況下就可以多次定次,最后確定
    參數(shù):key 公鑰
    lastPhase 是否最后公鑰

    public final SecretKey generateSecret(java.lang.String algorithm)
    throws java.lang.IllegalStateException,
    java.security.NoSuchAlgorithmException,
    java.security.InvalidKeyException
    根據(jù)指定的算法生成密鑰
    參數(shù):algorithm 加密算法(可用 DES,DESede,Blowfish)

    */
                import java.io.*;
                import java.math.BigInteger;
                import java.security.*;
                import java.security.spec.*;
                import java.security.interfaces.*;
                import javax.crypto.*;
                import javax.crypto.spec.*;
                import javax.crypto.interfaces.*;
                import com.sun.crypto.provider.SunJCE;
                public class testDHKey {
                public static void main(String argv[]) {
                try {
                testDHKey my= new testDHKey();
                my.run();
                } catch (Exception e) {
                System.err.println(e);
                }
                }
                private void run() throws Exception {
                Security.addProvider(new com.sun.crypto.provider.SunJCE());
                System.out.println("ALICE: 產(chǎn)生 DH 對(duì) ...");
                KeyPairGenerator aliceKpairGen = KeyPairGenerator.getInstance("DH");
                aliceKpairGen.initialize(512);
                KeyPair aliceKpair = aliceKpairGen.generateKeyPair(); //生成時(shí)間長(zhǎng)
                // 張三(Alice)生成公共密鑰 alicePubKeyEnc 并發(fā)送給李四(Bob) ,
                //比如用文件方式,socket.....
                byte[] alicePubKeyEnc = aliceKpair.getPublic().getEncoded();
                //bob接收到alice的編碼后的公鑰,將其解碼
                KeyFactory bobKeyFac = KeyFactory.getInstance("DH");
                X509EncodedKeySpec x509KeySpec = new X509EncodedKeySpec  (alicePubKeyEnc);
                PublicKey alicePubKey = bobKeyFac.generatePublic(x509KeySpec);
                System.out.println("alice公鑰bob解碼成功");
                // bob必須用相同的參數(shù)初始化的他的DH KEY對(duì),所以要從Alice發(fā)給他的公開密鑰,
                //中讀出參數(shù),再用這個(gè)參數(shù)初始化他的 DH key對(duì)
                //從alicePubKye中取alice初始化時(shí)用的參數(shù)
                DHParameterSpec dhParamSpec = ((DHPublicKey)alicePubKey).getParams();
                KeyPairGenerator bobKpairGen = KeyPairGenerator.getInstance("DH");
                bobKpairGen.initialize(dhParamSpec);
                KeyPair bobKpair = bobKpairGen.generateKeyPair();
                System.out.println("BOB: 生成 DH key 對(duì)成功");
                KeyAgreement bobKeyAgree = KeyAgreement.getInstance("DH");
                bobKeyAgree.init(bobKpair.getPrivate());
                System.out.println("BOB: 初始化本地key成功");
                //李四(bob) 生成本地的密鑰 bobDesKey
                bobKeyAgree.doPhase(alicePubKey, true);
                SecretKey bobDesKey = bobKeyAgree.generateSecret("DES");
                System.out.println("BOB: 用alice的公鑰定位本地key,生成本地DES密鑰成功");
                // Bob生成公共密鑰 bobPubKeyEnc 并發(fā)送給Alice,
                //比如用文件方式,socket.....,使其生成本地密鑰
                byte[] bobPubKeyEnc = bobKpair.getPublic().getEncoded();
                System.out.println("BOB向ALICE發(fā)送公鑰");
                // alice接收到 bobPubKeyEnc后生成bobPubKey
                // 再進(jìn)行定位,使aliceKeyAgree定位在bobPubKey
                KeyFactory aliceKeyFac = KeyFactory.getInstance("DH");
                x509KeySpec = new X509EncodedKeySpec(bobPubKeyEnc);
                PublicKey bobPubKey = aliceKeyFac.generatePublic(x509KeySpec);
                System.out.println("ALICE接收BOB公鑰并解碼成功");
                ;
                KeyAgreement aliceKeyAgree = KeyAgreement.getInstance("DH");
                aliceKeyAgree.init(aliceKpair.getPrivate());
                System.out.println("ALICE: 初始化本地key成功");
                aliceKeyAgree.doPhase(bobPubKey, true);
                // 張三(alice) 生成本地的密鑰 aliceDesKey
                SecretKey aliceDesKey = aliceKeyAgree.generateSecret("DES");
                System.out.println("ALICE: 用bob的公鑰定位本地key,并生成本地DES密鑰");
                if (aliceDesKey.equals(bobDesKey)) System.out.println("張三和李四的密鑰相同");
                //現(xiàn)在張三和李四的本地的deskey是相同的所以,完全可以進(jìn)行發(fā)送加密,接收后解密,達(dá)到
                //安全通道的的目的
                /*
                * bob用bobDesKey密鑰加密信息
                */
                Cipher bobCipher = Cipher.getInstance("DES");
                bobCipher.init(Cipher.ENCRYPT_MODE, bobDesKey);
                String bobinfo= "這是李四的機(jī)密信息";
                System.out.println("李四加密前原文:"+bobinfo);
                byte[] cleartext =bobinfo.getBytes();
                byte[] ciphertext = bobCipher.doFinal(cleartext);
                /*
                * alice用aliceDesKey密鑰解密
                */
                Cipher aliceCipher = Cipher.getInstance("DES");
                aliceCipher.init(Cipher.DECRYPT_MODE, aliceDesKey);
                byte[] recovered = aliceCipher.doFinal(ciphertext);
                System.out.println("alice解密bob的信息:"+(new String(recovered)));
                if (!java.util.Arrays.equals(cleartext, recovered))
                throw new Exception("解密后與原文信息不同");
                System.out.println("解密后相同");
                }
                }
    posted @ 2008-10-13 19:31 bt下載| 編輯 收藏

    關(guān)于應(yīng)用服務(wù)器和web服務(wù)器的整合,有很多的資料了,可是都講的半生不熟的。根據(jù)這幾天整合tomcat 和 iis 的經(jīng)驗(yàn),再次聊聊這個(gè)話題。

    首先我們應(yīng)該對(duì)應(yīng)用服務(wù)器和web服務(wù)器有一個(gè)清晰的概念。所謂的應(yīng)用服務(wù)器,就是提供應(yīng)用的服務(wù)器,這里的應(yīng)用有很多,比如java應(yīng)用,ruby 應(yīng)用,或者 c#應(yīng)用。

    那么什么是web服務(wù)器呢?就是提供了web功能的服務(wù)器,主要就是http服務(wù),包括圖片的下載,等等一系列和web相關(guān)的。

    好吧,你會(huì)問為什么我們不能直接使用應(yīng)用服務(wù)器呢?應(yīng)用服務(wù)器也提供了http服務(wù),比如tomcat。

    那么我們從實(shí)際出發(fā)。當(dāng)你瀏覽一個(gè)網(wǎng)頁的時(shí)候,什么情況下你會(huì)覺得速度很慢?我們僅僅考慮頁面本身。那當(dāng)然是圖片越多顯示得越慢。

    好吧,我們至少認(rèn)識(shí)到一點(diǎn),一些靜態(tài)資源,例如圖片,會(huì)嚴(yán)重影響頁面打開的速度。當(dāng)然,這僅僅是一個(gè)方面。

    那么web服務(wù)器有什么用呢?web服務(wù)器一個(gè)優(yōu)點(diǎn)就是在處理靜態(tài)信息上。例如一些靜態(tài)的html,圖片,等等其他靜態(tài)的東西。

    那為什么tomcat不能具備這些優(yōu)點(diǎn)?這個(gè)問題我們可以換一個(gè)說法:為什么會(huì)計(jì)不能做市場(chǎng)營(yíng)銷呢?

    所以嘛,大家要分工明確,應(yīng)用服務(wù)器就做好它該做的:如何解釋一個(gè)jsp,如何處理java文件等等,做好這一點(diǎn)就足夠了。而web服務(wù)器也做好它該做的:如何快速向?yàn)g覽器傳遞信息,如何快速地讓瀏覽器下載圖片。

    那你又問了,那為啥tomcat還提供一個(gè)http服務(wù)?那不是讓你開發(fā)方便嘛!千萬別把tomcat的http服務(wù)當(dāng)成是一個(gè)web服務(wù)器。

    說了這么多,那么我們對(duì)應(yīng)用服務(wù)器和web服務(wù)器的整合也應(yīng)該心里有數(shù)了。就拿tomcat和iis整合來說事吧!

    我們到底想干什么呢?很明顯,我們想讓tomcat 處理對(duì) java應(yīng)用的請(qǐng)求,而iis應(yīng)該處理圖片,css 等等其他靜態(tài)資源的事情。

    具體的細(xì)節(jié)不談了,無非就是配置 ispai_redirect 這個(gè)東東。因?yàn)槲覀冎饕f的分工問題,所以還是說說這個(gè) uriworkermap.properties 文件。

    這個(gè)文件就是處理分工的用的。例如我定義成如下這個(gè)樣子:
    /www.5a520.cn /eshop/*.do=ajp13
    /www.5a520.cn /eshop/dwr/interface/*=ajp13
    /www.5a520.cn /eshop/dwr/*=ajp13
    /www.bt285.cn /eshop/js/*=ajp13

    那么就告訴了 isapi_redirect , 以上4種請(qǐng)求,都交給tomcat處理。
    那么其他的請(qǐng)求呢?當(dāng)然是交給 iis了。

    如果我定義成這個(gè)樣子:
    /* = ajp13

    這下可慘了,iis被你浪費(fèi)了,就好像你招聘了一個(gè)會(huì)計(jì)和一個(gè)推銷的人員,但是讓會(huì)計(jì)干財(cái)務(wù)的活之外,還干了推銷。而推銷人員給閑置了。

    至于 uriworkermap.properties  的詳細(xì)配置,可以參考 tomcat 網(wǎng)站,上面有詳細(xì)的講解。


    兩種服務(wù)器的整合雖然不難,但是如果不明白其中的意義和原理,一旦項(xiàng)目配置有所變化,那就是沒有葫蘆就畫不出來瓢了。
    posted @ 2008-10-08 21:17 bt下載| 編輯 收藏

    mysql slow log 是用來記錄執(zhí)行時(shí)間較長(zhǎng)(超過long_query_time秒)的sql的一種日志工具.

    啟用 slow log

    有兩種啟用方式:
    1, 在my.cnf 里 通過 log-slow-queries[=file_name]
    2, 在mysqld進(jìn)程啟動(dòng)時(shí),指定--log-slow-queries[=file_name]選項(xiàng)

    比較的五款常用工具

    mysqldumpslow, mysqlsla, myprofi, mysql-explain-slow-log, mysqllogfilter


    mysqldumpslow, mysql官方提供的慢查詢?nèi)罩痉治龉ぞ? 輸出圖表如下:
    主要功能是, 統(tǒng)計(jì)不同慢sql的
    出現(xiàn)次數(shù)(Count), 
    執(zhí)行最長(zhǎng)時(shí)間(Time), 
    累計(jì)總耗費(fèi)時(shí)間(Time), 
    等待鎖的時(shí)間(Lock), 
    發(fā)送給客戶端的行總數(shù)(Rows), 
    掃描的行總數(shù)(Rows), 
    用戶以及sql語句本身(抽象了一下格式, 比如 limit 1, 20 用 limit N,N 表示).

    mysqlsla, hackmysql.com推出的一款日志分析工具(該網(wǎng)站還維護(hù)了 mysqlreport, mysqlidxchk 等比較實(shí)用的mysql工具)
    整體來說, 功能非常強(qiáng)大. 數(shù)據(jù)報(bào)表,非常有利于分析慢查詢的原因, 包括執(zhí)行頻率, 數(shù)據(jù)量, 查詢消耗等.

    格式說明如下:
    總查詢次數(shù) (queries total), 去重后的sql數(shù)量 (unique)
    輸出報(bào)表的內(nèi)容排序(sorted by)
    最重大的慢sql統(tǒng)計(jì)信息, 包括 平均執(zhí)行時(shí)間, 等待鎖時(shí)間, 結(jié)果行的總數(shù), 掃描的行總數(shù).

    Count, sql的執(zhí)行次數(shù)及占總的slow log數(shù)量的百分比.
    Time, 執(zhí)行時(shí)間, 包括總時(shí)間, 平均時(shí)間, 最小, 最大時(shí)間, 時(shí)間占到總慢sql時(shí)間的百分比.
    95% of Time, 去除最快和最慢的sql, 覆蓋率占95%的sql的執(zhí)行時(shí)間.
    Lock Time, 等待鎖的時(shí)間.
    95% of Lock , 95%的慢sql等待鎖時(shí)間.
    Rows sent, 結(jié)果行統(tǒng)計(jì)數(shù)量, 包括平均, 最小, 最大數(shù)量.
    Rows examined, 掃描的行數(shù)量.
    Database, 屬于哪個(gè)數(shù)據(jù)庫
    Users, 哪個(gè)用戶,IP, 占到所有用戶執(zhí)行的sql百分比

    Query abstract, 抽象后的sql語句
    Query sample, sql語句

    除了以上的輸出, 官方還提供了很多定制化參數(shù), 是一款不可多得的好工具.

    mysql-explain-slow-log, 德國(guó)人寫的一個(gè)perl腳本.
    http://www.willamowius.de/mysql-tools.html

    功能上有點(diǎn)瑕疵, 不僅把所有的 slow log 打印到屏幕上, 而且統(tǒng)計(jì)也只有數(shù)量而已. 不推薦使用.
    mysql-log-filter, google code上找到的一個(gè)分析工具.提供了 python 和 php 兩種可執(zhí)行的腳本.
    http://code.google.com/p/mysql-log-filter/
    功能上比官方的mysqldumpslow, 多了查詢時(shí)間的統(tǒng)計(jì)信息(平均,最大, 累計(jì)), 其他功能都與 mysqldumpslow類似.
    特色功能除了統(tǒng)計(jì)信息外, 還針對(duì)輸出內(nèi)容做了排版和格式化, 保證整體輸出的簡(jiǎn)潔. 喜歡簡(jiǎn)潔報(bào)表的朋友, 推薦使用一下.
    myprofi, 純php寫的一個(gè)開源分析工具.項(xiàng)目在 sourceforge 上.
    http://myprofi.sourceforge.net/

    功能上, 列出了總的慢查詢次數(shù)和類型, 去重后的sql語句, 執(zhí)行次數(shù)及其占總的slow log數(shù)量的百分比.
    從整體輸出樣式來看, 比mysql-log-filter還要簡(jiǎn)潔. 省去了很多不必要的內(nèi)容. 對(duì)于只想看sql語句及執(zhí)行次數(shù)的用戶來說, 比較推薦.

    總結(jié)

    工具/功能 一般統(tǒng)計(jì)信息 高級(jí)統(tǒng)計(jì)信息 腳本 優(yōu)勢(shì)
    mysqldumpslow 支持 不支持 perl mysql官方自帶
    mysqlsla 支持 支持 perl 功能強(qiáng)大,數(shù)據(jù)報(bào)表齊全,定制化能力強(qiáng).
    mysql-explain-slow-log 支持 不支持 perl
    mysql-log-filter 支持 部分支持 python or php 不失功能的前提下,保持輸出簡(jiǎn)潔
    myprofi 支持 不支持 php 非常精簡(jiǎn)
    posted @ 2008-10-07 23:33 bt下載| 編輯 收藏

    一、Java編碼是怎么回事?

    對(duì)于使用中文以及其他非拉丁語系語言的開發(fā)人員來說,經(jīng)常會(huì)遇到字符集編碼問題。對(duì)于Java語言來說,在其內(nèi)部使用的是UCS2編碼(2個(gè)字節(jié)的Unicode編碼)。這種編碼并不屬于某個(gè)語系的語言編碼,它實(shí)際上是一種編碼格式的世界語。在這個(gè)世界上所有可以在計(jì)算機(jī)中使用的語言都有對(duì)應(yīng)的UCS2編碼

    正是因?yàn)?/span>Java采用了UCS2,因此,在Java中可以使用世界上任何國(guó)家的語言來為變量名、方法名、類起名,如下面代碼如下:


    class 中國(guó)
    {
        
    public String 雄起()
        {
             
    return "中國(guó)雄起";
        }
    }

    中國(guó) 祖國(guó) 
    = new 中國(guó)();
    System.out.println(祖國(guó).雄起());

        哈哈,是不是有點(diǎn)象“中文編程”。實(shí)際上,也可以使用其他的語言來編程,如下面用韓文和日文來定義個(gè)類:

    class ???
    {
        
    public void スーパーマン() {  }
    }

        實(shí)際上,由于Java內(nèi)部使用的是UCS2編碼格式,因?yàn)椋?/span>Java并不關(guān)心所使用的是哪種語言,而只要這種語言在UCS2中有定義就可以。

        UCS2編碼中為不同國(guó)家的語言進(jìn)行了分頁,這個(gè)分頁也叫“代碼頁”或“編碼頁”。中文根據(jù)包含中文字符的多少,分了很多代碼頁,如cp935cp936等,然而,這些都是在UCS2中的代碼頁名,而對(duì)于操作系統(tǒng)來說,如微軟的windows,一開始的中文編碼為GB2312,后來擴(kuò)展成了GBK。其實(shí)GBKcp936是完全等效的,用它們哪個(gè)都行。

    二、Java編碼轉(zhuǎn)換

       
    上面說了這么多,在這一部分我們做一些編碼轉(zhuǎn)換,看看會(huì)發(fā)生什么事情。

        先定義一個(gè)字符串變量:

        String gbk = "
    中國(guó)"; // “中國(guó)”在Java內(nèi)部是以UCS2格式保存的

        用下面的語言輸出一定會(huì)輸出中文:

    System.out.println(gbk);

        實(shí)現(xiàn)上,當(dāng)我們從IDE輸入“中國(guó)”時(shí),用的是java源代碼文件保存的格式,一般是GBK,有時(shí)也可是utf-8,而在Java編譯程序時(shí),會(huì)不由分說地將所有的編碼格式轉(zhuǎn)換成utf-8編碼,讀者可以用UltraEdit或其他的二進(jìn)制編輯器打開上面的“中國(guó).class”,看看所生成的二進(jìn)制是否有utf-8的編碼(utf-8ucs2之間的轉(zhuǎn)換非常容易,因?yàn)?/span>utf-8ucs2之間是用公式進(jìn)行轉(zhuǎn)換的,而不是到代碼頁去查,這就相當(dāng)于將二進(jìn)制轉(zhuǎn)成16進(jìn)制一樣,4個(gè)字節(jié)一組)。如“中國(guó)”的utf-8編碼按著GBK解析就是“涓  浗”。如下圖所示。



    如果使用下面的語言可以獲得“中國(guó)”的utf-8字節(jié),結(jié)果是6(一個(gè)漢字由3個(gè)字節(jié)組成)

    System.out.println(gbk.getBytes("utf-8").length);

    下面的代碼將輸出“涓  浗”。

    System.out.println(new String(gbk.getBytes("utf-8"), "gbk"));   

    由于將“中國(guó)“的utf-8編碼格式按著gbk解析,所以會(huì)出現(xiàn)亂碼。

    如果要返回中文的UCS2編碼,可以使用下面的代碼:

    System.out.println(gbk.getBytes("unicode")[2]);

    System.out.println(gbk.getBytes("unicode")[3]);

    前兩個(gè)字節(jié)是標(biāo)識(shí)位,要從第3個(gè)字節(jié)開始。還有就是其他的語言使用的編碼的字節(jié)順序可能不同,如在C#中可以使用下面的代碼獲得“中國(guó)“的UCS2編碼:

    String s = "
    ";

    MessageBox.Show(ASCIIEncoding.Unicode.GetBytes(s)[0].ToString());

    MessageBox.Show(ASCIIEncoding.Unicode.GetBytes(s)[1].ToString());

        使用上面的java代碼獲得的“中“的16進(jìn)制UCS2編碼為4E2D,而使用C#獲得的相應(yīng)的ucs2編碼為2D4E,這只是C#Java編碼內(nèi)部使用的問題,并沒有什么關(guān)系。但在C#Java互操作時(shí)要注意這一點(diǎn)。

        如果使用下面的java編碼將獲得16進(jìn)制的“中”的GBK編碼:

    System.out.println(Integer.toHexString(0xff & xyz.getBytes("gbk")[0]));

    System.out.println(Integer.toHexString(0xff & xyz.getBytes("gbk")[1]));

    “中”的ucs2編碼為2D4EGBK編碼為D6D0

        讀者可訪問如下的url自行查驗(yàn):

        http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP936.TXT

        當(dāng)然,感興趣的讀者也可以試試其他語言的編碼,如“人類”的韓語是“???”,如下面的代碼將輸出“???”的cp949ucs2編碼,其中cp949是韓語的代碼頁。


    String korean = "???"// 共三個(gè)韓文字符,我們只測(cè)試第一個(gè)“?”

    System.out.println(Integer.toHexString(
    0xff & korean.getBytes("unicode")[2]));

    System.out.println(Integer.toHexString(
    0xff & korean.getBytes("unicode")[3]));

    System.out.println(Integer.toHexString(
    0xff & korean.getBytes("Cp949")[0]));

    System.out.println(Integer.toHexString(
    0xff & korean.getBytes("Cp949")[1]));

     

    上面代碼的輸出結(jié)果如下:

    c7

    78

    c0

    ce

        也就是說“?”的ucs2編碼為C778cp949的編碼為C0CE,要注意的是,在cp949中,ucs2編碼也有C0CE,不要弄混了。讀者可以訪問下面的url來驗(yàn)證:

    http://unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP949.TXT

    http://www.bt285.cn/content.php?id=1196863

    Java支持的編碼格式

    三、屬性文件

    Java中的屬性文件只支持iso-8859-1編碼格式,因此,要想在屬性文件中保存中文,就必須使用UCS2編碼格式("uxxxx),因此,出現(xiàn)了很多將這種編碼轉(zhuǎn)換成可視編碼和工具,如Eclipse中的一些屬性文件編輯插件。

    實(shí)際上,"uxxxx編碼格式在javaC#中都可以使用,如下面的語句所示:

    String name= ""u7528"u6237"u540d"u4e0d"u80fd"u4e3a"u7a7a" ;

    System.out.println(name);

        上面代碼將輸出“用戶名不能為空”的信息。將"uxxxx格式顯示成中文非常簡(jiǎn)單,那么如何將中文還原成"uxxxxx格式呢?下面的代碼完成了這個(gè)工作:


    String ss = "用戶名不能為空";
    byte[] uncode = ss.getBytes("Unicode");
    int x = 0xff;
    String result 
    ="";
    for(int i= 2; i < uncode.length; i++)
    {
        
    if(i % 2 == 0) result += "\\u";
        String abc 
    = Integer.toHexString(x & uncode[i]);            
        result 
    += abc.format("%2s", abc).replaceAll(" ""0");               
    }
    System.out.println(result);

     

        上面的代碼將輸出如下結(jié)果:


    \u7528\u6237\u540d\u4e0d\u80fd\u4e3a\u7a7a

        好了,現(xiàn)在可以利用這個(gè)技術(shù)來實(shí)現(xiàn)一個(gè)屬性文件編輯器了。

    四、Web中的編碼問題

        大家碰到最多的編碼問題就是在Web應(yīng)用中。先讓我們看看下面的程序:

     

    <!--  main.jsp  -->

      
    <%@ page language="java"  pageEncoding="utf-8"%>

      
    <html>
          
    <head>

          
    </head>

          
    <body>
              
    <form action="servlet/MyPost" method="post">
                  
    <input type="text" name="user" />
                  
    <p/>
                  
    <input type="submit"  value="提交"/>
              
    </form>

          
    </body>
      
    </html>


        下面是個(gè)Servlet

      package servlet;

      import java.io.IOException;
      import java.io.PrintWriter;
      import javax.servlet.ServletException;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;

      
    public class MyPost extends HttpServlet
      {

          
    public void doPost(HttpServletRequest request, HttpServletResponse response)
                  throws ServletException, IOException
          {
              String user 
    = request.getParameter("user");
              System.
    out.println(user);
          }
      }


        如果中main.jsp中輸入中文后,向MyPost提交,在控制臺(tái)中會(huì)輸出“中å?½”,一看就是亂碼。如果將IE的當(dāng)前編碼設(shè)成其他的,如由utf-8改為gbk,仍然會(huì)出現(xiàn)亂碼,只是亂得不一樣而已。這是因?yàn)榭蛻舳颂峤粩?shù)據(jù)時(shí)是根據(jù)瀏覽器當(dāng)前的編碼格式來提交的,如瀏覽器當(dāng)前為gbk編碼,就以gbk編碼格式來提交。 這本身是不會(huì)出現(xiàn)亂碼的,問題就出在Web服務(wù)器接收數(shù)據(jù)的時(shí)候,HttpServletRequest在將客戶端傳來的數(shù)據(jù)轉(zhuǎn)成ucs2上出了問題。在默認(rèn)情況下,是按著iso-8859-1編碼格式來轉(zhuǎn)的,而這種編碼格式并不支持中文,所以也就無法正常顯示中文了,解決這個(gè)問題的方法是用和客戶端瀏覽器當(dāng)前編碼格式一致的編碼來轉(zhuǎn)換,如果是utf-8,則在doPost方法中應(yīng)該用以下的語句來處理:

        request.setCharacterEncoding("utf-8");

        為了對(duì)每一個(gè)Servlet都起作用,可以將上面的語句加到filter里。

        另外,我們一般使用象MyEclipse一樣的IDE來編寫jsp文件,這樣的工具會(huì)根據(jù)pageEncoding屬性將jsp文件保存成相應(yīng)的編碼格式,但如果要使用象記事本一樣的簡(jiǎn)單的編輯器來編寫jsp文件,如果pageEncodingutf-8,而在默認(rèn)時(shí),記事本會(huì)將文件保存成iso-8859-1ascii)格式,但在myeclipse里,如果文件中有中文,它是不允許我們保存成不支持中文的編碼格式的,但記事本并不認(rèn)識(shí)jsp,因此,這時(shí)在ie中就無法正確顯示出中文了。除非用記事本將其保存在utf-8格式。如下圖:


     

    http://blog.csdn.net/wangdei/archive/2008/10/07/3030758.aspx
    posted @ 2008-10-07 22:36 bt下載 閱讀(513) | 評(píng)論 (0)編輯 收藏

    主站蜘蛛池模板: 亚洲宅男天堂a在线| 亚洲精品熟女国产| 精品久久久久久亚洲中文字幕| 国产成人亚洲精品蜜芽影院| 国产成人yy免费视频| 亚洲国产精品成人久久久| 久久精品国产免费观看三人同眠| 四只虎免费永久观看| 特a级免费高清黄色片| 亚洲成AV人网址| 一级毛片免费播放试看60分钟| 日韩一级在线播放免费观看| 亚洲视频免费在线观看| 久久九九亚洲精品| 欧洲精品99毛片免费高清观看| 亚洲精品~无码抽插| 一级毛片免费观看不卡视频| 亚洲欧洲第一a在线观看| 1000部拍拍拍18免费网站| 亚洲一卡一卡二新区无人区| 国产免费小视频在线观看| 一边摸一边爽一边叫床免费视频| 亚洲男人在线无码视频| 免费人成在线观看网站| 亚洲一卡2卡4卡5卡6卡在线99| 女性自慰aⅴ片高清免费| 日韩色视频一区二区三区亚洲| 在线免费一区二区| 国产精品免费大片一区二区| 亚洲国产精品一区二区久久| 噼里啪啦电影在线观看免费高清| 亚洲中文精品久久久久久不卡| 精品少妇人妻AV免费久久洗澡| 色九月亚洲综合网| 亚洲精品二区国产综合野狼| 91短视频免费在线观看| 美女18一级毛片免费看| 一区二区三区亚洲| 国产美女无遮挡免费视频| 国产成人无码区免费网站| 亚洲国产成a人v在线观看|