天天看點

編碼和加密

在用javascript對url字元串進行編碼

中,雖然escape()、encodeuri()、encodeuricomponent()三種方法都能對一些影響url完整性的特殊字元進行過濾。

但後兩者是将字元串轉換為utf-8的方式來傳輸,解決了頁面編碼不一至導緻的亂碼問題。例如:發送頁與接受頁的編碼格式(charset)不一緻(假設

發送頁面是gb2312而接收頁面編碼是utf-8),使用escape()轉換傳輸中文字串就會出現亂碼問題。 

以下是js下對url進行編/解碼的各種方法: 

1、escape 方法:傳回一個可在所有計算機上讀取的編碼 string 對象。 

function escape(charstring : string) : string  

不會被此方法編碼的字元: @ * / +  

說明:escape 方法傳回一個包含 charstring 内容的字元串值(unicode 格式)。所有空格、标點、 

重音符号以及任何其他非 ascii 字元都用 %xx 編碼替換,其中 xx 等于表示該字元的十六進制數。 

例如,空格傳回為“%20”。(字元值大于 255 的字元以 %uxxxx 格式存儲。) 

注意:escape 方法不能用來對“統一資源辨別符”(uri) 進行編碼。對其編碼應使用 encodeuri 和encodeuricomponent 方法。 

2、encodeuri 方法:傳回編碼為有效的統一資源辨別符 (uri) 的字元串。 

function encodeuri(uristring : string) : string  

不會被此方法編碼的字元:! @ # $ & * ( ) = : / ; ? + ‘  

說明:encodeuri 方法傳回一個已編碼的 uri。如果将編碼結果傳遞給 decodeuri,則将傳回初始的字元串。encodeuri 不對下列字元進行編碼:“:”、“/”、“;”和“?”。請使用 

encodeuricomponent 對這些字元進行編碼。 

3、encodeuricomponent方法:傳回編碼為統一資源辨別符 (uri) 的有效元件的字元串。 

function encodeuricomponent(encodeduristring : string) : string  

不會被此方法編碼的字元:! * ( ) ‘  

說明:encodeuricomponent 方法傳回一個已編碼的 uri。如果将編碼結果傳遞給decodeuricomponent,則将傳回初始的字元串。因為 encodeuricomponent 方法将對所有字元編碼, 

請注意,如果該字元串代表一個路徑,例如 /folder1/folder2/default.html,則其中的斜杠也将被編碼,這樣,當該字元串作為請求發送到 web 伺服器時它将是無效的。如果字元串中包含多個 uri 元件,請使用 encodeuri 方法進行編碼。 

4、unescape方法:從用 escape 方法編碼的 string 對象中傳回已解碼的字元串。 

function unescape(charstring : string) : string  

說明:unescape 方法傳回一個包含 charstring 内容的字元串值。所有以 %xx 十六進制形式編碼的 

字元都用 ascii 字元集當中等效的字元代替。(以 %uxxxx 格式(unicode 字元)編碼的字元用十六 

進制編碼 xxxx 的 unicode 字元代替。) 

注意:unescape 方法不應用于解碼“統一資源辨別符”(uri)。請改用 decodeuri 和 decodeuricomponent 方法。 

5、decodeuri 方法:傳回一個已編碼的統一資源辨別符 (uri) 的非編碼形式。 

function decodeuri(uristring : string) : string  

decodeuricomponent 方法:傳回統一資源辨別符 (uri) 的一個已編碼元件的非編碼形式。 

function decodeuricomponent(encodeduristring : string) : string  

btw:c#中對url編碼的方法。。。 

編碼:server.urlencode(string)  

解碼:server.urldecode(string) 前面三種用戶端編碼都可以用這個方法在背景解碼。

關于httputility.urlencode,httputility.urldecode,server.urlencode,server.urldecode

httputility.urlencode 方法:

對 url 字元串進行編碼,以便實作從 web 伺服器到用戶端的可靠的 http 傳輸。

重載清單 

将位元組數組轉換為已編碼的 url 字元串,以便實作從 web 伺服器到用戶端的可靠的 http 傳輸。 

[c#] public static string urlencode(byte[]);

對 url 字元串進行編碼,以便實作從 web 伺服器到用戶端的可靠的 http 傳輸。 

[c#] public static string urlencode(string);

使用指定的編碼對象對 url 字元串進行編碼,以便實作從 web 伺服器到用戶端的可靠 http 傳輸。 

[c#] public static string urlencode(string, encoding);

從數組中的指定位置開始一直到指定的位元組數為止,将位元組數組轉換為 url 編碼的字元串,以便實作從 web 伺服器到用戶端的可靠的 http 傳輸。 

[c#] public static string urlencode(byte[], int, int);

httputility.urldecode 方法:

将已經為在 url 中傳輸而編碼的字元串轉換為解碼的字元串。

将已經為在 url 中傳輸而編碼的字元串轉換為解碼的字元串。 

[c#] public static string urldecode(string);

使用指定的解碼對象将 url 編碼的位元組數組轉換為已解碼的字元串。 

[c#] public static string urldecode(byte[], encoding);

使用指定的編碼對象将 url 編碼的字元串轉換為已解碼的字元串。 

[c#] public static string urldecode(string, encoding);

使用指定的編碼對象,從數組中的指定位置開始到指定的位元組數為止,将 url 編碼的位元組數組轉換為已解碼的字元串。 

[c#] public static string urldecode(byte[], int, int, encoding);

server是httpserverutility類的執行個體,是system.web.ui.page的屬性。 

httpserverutility.urlencode 方法: 

編碼字元串,以便通過 url 從 web 伺服器到用戶端進行可靠的 http 傳輸。

對字元串進行 url 編碼,并傳回已編碼的字元串。 

[c#] public string urlencode(string);

url 對字元串進行編碼,并将結果輸出發送到 textwriter 輸出流。 

[c#] public void urlencode(string, textwriter); 

例: 

string teststring = "this is a <test string>."; 

stringwriter writer = new stringwriter(); 

server.urlencode(teststring, writer); 

string encodedstring = writer.tostring();

httpserverutility.urldecode 方法:

對字元串進行解碼,該字元串為了進行 http 傳輸而進行編碼并在 url 中發送到伺服器。

對字元串進行 url 解碼并傳回已解碼的字元串。 

[c#] public string urldecode(string);

對在 url 中接收的 html 字元串進行解碼,并将結果輸出發送到 textwriter 輸出流。 

[c#] public void urldecode(string, textwriter);

需要注意的幾點:

1、httputility.urlencode,httputility.urldecode是靜态方法,而server.urlencode,server.urldecode是執行個體方法。 

2、server是httpserverutility類的執行個體,是system.web.ui.page的屬性。 

3、用httputility.urlencode編碼後的字元串和用server.urlencode進行編碼後的字元串對象不一樣: 

例如: 

string url="http://search.99read.com/index.aspx?book_search=all&main_str=奧迷爾"; 

response.write(httputility.urlencode(url)); 

response.write("<br>"); 

response.write(server.urlencode(url));

輸出結果是: 

http%3a%2f%2fsearch.99read.com%2findex.aspx%3fbook_search%3dall%26main_str%3d%e5%a5%a5%e8%bf%b7%e5%b0%94 

http%3a%2f%2fsearch.99read.com%2findex.aspx%3fbook_search%3dall%26main_str%3d%b0%c2%c3%d4%b6%fb

原因:server.urlencode的編碼方式是按照本地程式設定的編碼方式進行編碼的,而httputility.urlencode是預設的按照.net的utf-8格式進行編碼的。

如果改一下程式: 

string url1="http://search.99read.com/index.aspx?book_search=all&main_str=奧迷爾"; 

response.write(httputility.urlencode(url1,system.text.encoding.getencoding("gb2312"))); 

response.write(server.urlencode(url1));

輸出的結果是: 

http%3a%2f%2fsearch.99read.com%2findex.aspx%3fbook_search%3dall%26main_str%3d%b0%c2%c3%d4%b6%fb 

4、有時候可能别的系統傳遞過來的url是用别的編碼方式編碼的。 

介紹自己編寫的一個方法,可以擷取指定編碼格式的querystring。

public string getnonnullquerystring(string key,encoding encoding) 

   //引用system.collections.specialized和system.text命名空間 

   string stringvalue; 

   system.collections.specialized.namevaluecollection encodingquerystring; 

   //該方法是在2.0中新增的 

   encodingquerystring = httputility.parsequerystring(request.url.query,encoding); 

   //‘裡面的key就是你送出的參數的key 

   return encodingquerystring[key] != null ? encodingquerystring[key].trim() : ""; 

}

調用: 

string url = getnonnullquerystring("url",encoding.utf8).trim();

在對url進行編碼時,該用哪一個?這兩都使用上有什麼差別嗎? 

測試: 

string file="檔案上(傳)篇.doc"; 

string server_urlencode=server.urlencode(file); 

string server_urldecode=server.urldecode(server_urlencode); 

string httputility_urlencode=system.web.httputility.urlencode(file); 

string httputility_urldecode=system.web.httputility.urldecode(httputility_urlencode); 

response.write("原資料:"+file); 

sfun.writeline("server.urlencode:"+server_urlencode); 

sfun.writeline("server.urldecode:"+server_urldecode); 

sfun.writeline("httputility.urlencode:"+httputility_urlencode); 

sfun.writeline("httputility.urldecode:"+httputility_urldecode); 

輸出: 

原資料:檔案上(傳)篇.doc 

server.urlencode:%ce%c4%bc%fe%c9%cf%a3%a8%b4%ab%a3%a9%c6%aa.doc 

server.urldecode:檔案上(傳)篇.doc 

httputility.urlencode:%e6%96%87%e4%bb%b6%e4%b8%8a%ef%bc%88%e4%bc%a0%ef%bc%89%e7%af%87.doc 

httputility.urldecode:檔案上(傳)篇.doc 

差別在于:httputility.urlencode()預設是以utf8對url進行編碼,而server.urlencode()則以預設的編碼對url進行編碼。 

在用 asp.net 開發頁面的時候, 我們常常通過 system.web.httputility.urlencode 和 urldecode 在頁面間通過 url 傳遞參數. 成對的使用 encode 和 decode 是沒有問題的. 

但是, 我們在編寫檔案下載下傳的頁面的時候, 常常用如下方法來指定下載下傳的檔案的名稱: 

response.addheader("content-disposition","attachment; filename=" 

+ httputility.urlencode(filename, encoding.utf8)); 

之是以轉換成 utf8 是為了支援中文檔案名. 

這 時

候問題就來了, 因為 httputility.urlencode 在 encode 的時候, 将空格轉換成加号(‘+‘), 在 decode 的

時候将加号轉為空格, 但是浏覽器是不能了解加号為空格的, 是以如果檔案名包含了空格, 在浏覽器下載下傳得到的檔案, 空格就變成了加号. 

一個解決辦法是, 在 httputility 的 urlencode 之後, 将 "+" 替換成 "%20"( 如果原來是 "+" 則被轉換成 "%2b" ) , 如: 

filename = httputility.urlencode(filename, encoding.utf8); 

filename = filename.replace("+", "%20"); 

不明白微軟為什麼要把空格轉換成加号而不是"%20". 記得 jdk 的 urlencoder 是将空格轉換成 "%20"的. 

經檢查, 在 .net 2.0 也是這樣. 

時候預設aspx是以utf-8為編碼的,你的程式預設編碼

(<globalization requestencoding="gb2312" responseencoding="gb2312"/&

gt;),問題出現了,以前沒有問題的httputility.urldecode在page.request回的值是亂碼這就是上面說的

httputility.urldecode預設以utf8對url進行編碼,這種情況下面隻需将httputility.urldecode改成

server.urlencode即可。

二.js加密解密

在做網頁時(其實是網頁木馬呵呵),最讓人煩惱的是自己辛辛苦苦寫出來的用戶端ie運作的javascript代碼常常被别人輕易的拷貝,實在讓自己的心裡有點不是滋味,要知道自己寫點東西也挺累的

編碼和加密
編碼和加密

^*^

    以加密下面的javascript代碼為例:

<script language="javascript">

alert("《我愛一起》");

</script>

  一:最簡單的加密解密

  大家對于javascript函數escape()和unescape()想必是比較了解啦(很多網頁加密在用它們),分别是編碼和解碼字元串,比如例子代碼用escape()函數加密後變為如下格式:

alert%28%22%u9ed1%u5ba2%u9632%u7ebf%22%29%3b

  如何?還看的懂嗎?當然其中的ascii字元"alert"并沒有被加密,如果願意我們可以寫點javascript代碼重新把它加密如下:

%61%6c%65%72%74%28%22%u9ed1%u5ba2%u9632%u7ebf%22%29%3b

  呵呵!如何?這次是完全都加密了!

 

 當然,這樣加密後的代碼是不能直接運作的,幸好還有eval(codestring)可用,這個函數的作用就是檢查javascript代碼并執行,必

選項 codestring 參數是包含有效 javascript 代碼的字元串值,加上上面的解碼unescape(),加密後的結果如下:

var code=unescape("%61%6c%65%72%74%28%22%u9ed1%u5ba2%u9632%u7ebf%22%29%3b");

eval(code)

  是不是很簡單?不要高興,解密也就同樣的簡單,解密代碼都擺給别人啦(unescape())!呵呵

  二:轉義字元""的妙用

 大家可能對轉義字元""不太熟悉,但對于javascript提供了一些特殊字元如:n (換行)、 r (回車)、‘ (單引号)等應該是有所了解的

吧?其實""後面還可以跟八進制或十六進制的數字,如字元"a"則可以表示為:"141"或"x61"(注意是小寫字元"x"),至于雙位元組字元如漢字"

黑"則僅能用十六進制表示為"u9ed1"(注意是小寫字元"u"),其中字元"u"表示是雙位元組字元,根據這個原理例子代碼則可以表示為:

  八進制轉義字元串如下:

eval("1411541451621645042u9ed1u5ba2u9632u7ebf425173")

  十六進制轉義字元串如下:

eval("x61x6cx65x72x74x28x22u9ed1u5ba2u9632u7ebfx22x29x3b")

  這次沒有了解碼函數,因為javascript執行時會自行轉換,同樣解碼也是很簡單如下:

alert("x61x6cx65x72x74x28x22u9ed1u5ba2u9632u7ebfx22x29x3b")

  就會彈出對話框告訴你解密後的結果!

  三:使用microsoft出品的腳本編碼器script encoder來進行編碼

  工具的使用就不多介紹啦!我是直接使用javascript調用控件scripting.encoder完成的編碼!代碼如下:

var senc=new activexobject("scripting.encoder");

var code=‘<script language="javascript">rnalert("《我愛一起》");rn</script>‘;

var encode=senc.encodescriptfile(".htm",code,0,"");

alert(encode);

  編碼後的結果如下:

<script language="jscript.encode">#@~^fgaaaa==@#@&ls dd`j黑客防線r#p@#@&fgmaaa==^#~@</script>

  夠難看懂得吧?但相應的解密工具早已出來,而且連解密網頁都有!因為其解密網頁代碼過多,我就不多說拉!給大家介紹一下我獨創的解密代碼,如下:

<script language="jscript.encode">

function decode()

alert(decode.tostring());

  咋樣?夠簡單吧?它是原理是:編碼後的代碼運作前ie會先對其進行解碼,如果我們先把加密的代碼放入一個自定義函數如上面的decode()中,然後對自定義函數decode調用tostring()方法,得到的将是解碼後的代碼!

  如果你覺得這樣編碼得到的代碼language屬性是jscript.encode,很容易讓人識破,那麼還有一個幾乎不為人知的window對象的方法execscript(),其原形為:

  window.execscript( sexpression, slanguage )

  參數:

sexpression:  必選項。字元串(string)。要被執行的代碼。

slanguage :  必選項。字元串(string)。指定執行的代碼的語言。預設值為 microsoft jscript

使用時,前面的"window"可以省略不寫!

  利用它我們可以很好的運作編碼後的javascript代碼,如下:

execscript("#@~^fgaaaa==@#@&ls dd`j我愛一起r#p@#@&fgmaaa==^#~@","jscript.encode")

  你可以利用方法二對其中的""号内的字元串再進行編碼,使得"jscript.encode"以及編碼特征碼"#@~^"不出現,效果會更好!

  四:任意添加nul空字元(十六進制00h)

 一次偶然的實驗,使我發現在html網頁中任意位置添加任意個數的"空字元",ie照樣會正常顯示其中的内容,并正常執行其中的

javascript 代碼,而添加的"空字元"我們在用一般的編輯器檢視時,會顯示形如空格或黑塊,使得原碼很難看懂,如用記事本檢視則"空字元"會變

成"空格",利用這個原理加密結果如下:(其中顯示的"空格"代表"空字元")

<s c ri p t l ang u a g e =" j a v a s c r i p t "> 

a l er t (" 我 愛 一 起") ; 

< / sc r i p t>

  如何?是不是顯得亂七八糟的?如果不知道方法的人很難想到要去掉裡面的"空字元"(00h)的!

  五:無用内容混亂以及換行空格tab大法

 在javascript代碼中我們可以加入大量的無用字元串或數字,以及無用代碼和注釋内容等等,使真正的有用代碼埋沒在其中,并把有用的代碼中能加入

換行、空格、tab的地方加入大量換行、空格、tab,并可以把正常的字元串用""來進行換行,這樣就會使得代碼難以看懂!如我加密後的形式如下:

"xajgxsadffgds";1234567890

625623216;var $=0;alert//@$%%&*()(&(^%^

//cctv function//

(//hhsaasajx xc

/*

asjgdsgu*/

"我愛一起"//ashjgfgf

@#%$^&%$96667r45fggbhytjty

*/

//window

)

;"#@$#%@#432hu";212351436

  至少如果我看到這樣的代碼是不會有心思去分析它的,你哪?

  六:自寫解密函數法

  這個方法和一、二差不多,隻不過是自己寫個函數對代碼進行解密,很多vbs病毒使用這種方法對自身進行加密,來防止特征碼掃描!下面是我寫的一個簡單的加密解密函數,加密代碼如下(詳細參照檔案"加密.htm"):

function compile(code)

var c=string.fromcharcode(code.charcodeat(0)+code.length);

for(var i=1;i<code.length;i++)

alert(escape(c));

compile(‘alert("《我愛一起》");‘)

  運作得到加密結果為:

o%cd%d1%d7%e6%9cj%u9ef3%ufa73%uf1d4%u14f1%u7ee1kd

  相應的加密後解密的代碼如下:

function uncompile(code)

{

code=unescape(code);

var c=string.fromcharcode(code.charcodeat(0)-code.length);

return c;

eval(uncompile("o%cd%d1%d7%e6%9cj%u9ef3%ufa73%uf1d4%u14f1%u7ee1kd"));

  七:錯誤的利用

  利用try{}catch(e){}結構對代碼進行測試解密,雖然這個想法很好(呵呵,誇誇自己),因為實用性不大,我僅給個例子

var a=‘alert("《我愛一起》");‘;

var c="";

for(var i=0;i<a.length;i++)

alert(c);

//上面的是加密代碼,當然如果真正使用這個方法時,不會把加密寫上的

//現在變量c就是加密後的代碼

//下面的函數t()先假設初始密碼為0,解密執行,

//遇到錯誤則把密碼加1,然後接着解密執行,直到正确運作

var d=c; //儲存加密後的代碼

var b=0; //假定初始密碼為0

t();

function t()catch(e){

c="";

for(var i=0;i<d.length;i++)

b+=1;

//settimeout("t()",0);

三。實作server.urlencode和server.urldecode的js代碼

var encodeuri = function(unzipstr,iscusencode){

    if(iscusencode){

        var ziparray = new array();

        var zipstr = "";

        var lens = new array();

        for(var i=0;i<unzipstr.length;i++){

         var ac = unzipstr.charcodeat(i);

         zipstr += ac;

         lens = lens.concat(ac.tostring().length);

        } 

        ziparray = ziparray.concat(zipstr);

        ziparray = ziparray.concat(lens.join("o"));

        return ziparray.join("n");

    }else{

        //return encodeuri(unzipstr);

        var zipstr=""; 

        var strspecial="!\"#$%&‘()*+,/:;<=>?[]^`{|}~%"; 

        var tt= "";

        for(var i=0;i<unzipstr.length;i++){ 

            var chr = unzipstr.charat(i); 

            var c=stringtoascii(chr); 

            tt += chr+":"+c+"n"; 

            if(parseint("0x"+c) > 0x7f){ 

                 zipstr+=encodeuri(unzipstr.substr(i,1));

            }else{ 

                 if(chr==" ") 

                    zipstr+="+"; 

                 else if(strspecial.indexof(chr)!=-1) 

                    zipstr+="%"+c.tostring(16); 

                 else 

                    zipstr+=chr; 

                } 

            } 

        return zipstr; 

    }

var decodeuri = function(zipstr,iscusencode){

        var ziparray = zipstr.split("n");

        var zipsrcstr = ziparray[0];

        var ziplens;

        if(ziparray[1]){

            ziplens = ziparray[1].split("o");    

        }else{

            ziplens.length = 0;

        }

        var uzipstr = "";

        for(var j=0;j<ziplens.length;j++){

            var charlen = parseint(ziplens[j]);

            uzipstr+= string.fromcharcode(zipsrcstr.substr(0,charlen));

            zipsrcstr = zipsrcstr.slice(charlen,zipsrcstr.length);

        }        

        return uzipstr;

        //return decodeuri(zipstr);

        var uzipstr=""; 

        for(var i=0;i<zipstr.length;i++){ 

            var chr = zipstr.charat(i); 

            if(chr == "+"){ 

                 uzipstr+=" "; 

            }else if(chr=="%"){ 

                 var asc = zipstr.substring(i+1,i+3); 

                 if(parseint("0x"+asc)>0x7f){ 

                     uzipstr+=decodeuri("%"+asc.tostring()+zipstr.substring(i+3,i+9).tostring()); ; 

                     i+=8; 

                 }else{ 

                     uzipstr+=asciitostring(parseint("0x"+asc)); 

                     i+=2; 

                 } 

                 uzipstr+= chr; 

var stringtoascii = function(str){

    return str.charcodeat(0).tostring(16);

var asciitostring = function(asccode){

    return string.fromcharcode(asccode);