MD5

簡介

MD5(單向散列算法)的全稱是Message-Digest Algorithm 5(信息-摘要算法),經(jīng)MD2绿淋、MD3和MD4發(fā)展而來。MD5算法的使用不需要支付任何版權(quán)費用。

MD5功能

輸入任意長度的信息晒旅,經(jīng)過處理富稻,輸出為128位的信息(數(shù)字指紋)掷邦; 不同的輸入得到的不同的結(jié)果(唯一性); 根據(jù)128位的輸出結(jié)果不可能反推出輸入的信息(不可逆)椭赋;

MD5屬不屬于加密算法

認為不屬于的人是因為他們覺得不能從密文(散列值)反過來得到原文抚岗,即沒有解密算法,所以這部分人認為MD5只能屬于算法哪怔,不能稱為加密算法宣蔚; 認為屬于的人是因為他們覺得經(jīng)過MD5處理后看不到原文,即已經(jīng)將原文加密认境,所以認為MD5屬于加密算法胚委;我個人支持后者。

MD5用途

  • 防止被篡改

    • 比如發(fā)送一個電子文檔叉信,發(fā)送前亩冬,我先得到MD5的輸出結(jié)果a。然后在對方收到電子文檔后硼身,對方也得到一個MD5的輸出結(jié)果b硅急。如果a與b一樣就代表中途未被篡改覆享。
  • 比如我提供文件下載,為了防止不法分子在安裝程序中添加木馬营袜,我可以在網(wǎng)站上公布由安裝文件得到的MD5輸出結(jié)果撒顿。

  • SVN在檢測文件是否在CheckOut后被修改過,也是用到了MD5.

  • 防止直接看到明文
    現(xiàn)在很多網(wǎng)站在數(shù)據(jù)庫存儲用戶的密碼的時候都是存儲用戶密碼的MD5值连茧。這樣就算不法分子得
    到數(shù)據(jù)庫的用戶密碼的MD5值核蘸,也無法知道用戶的密碼(其實這樣是不安全的,后面我會提到)啸驯。(比如在UNIX系統(tǒng)中用戶的密碼就是以MD5(或其它類似的算法)經(jīng)加密后存儲在文件系統(tǒng)中客扎。當(dāng)用戶登錄的時候,系統(tǒng)把用戶輸入的密碼計算成MD5值罚斗,然后再去和保存在文件系統(tǒng)中的MD5值進行比較徙鱼,進而確定輸入的密碼是否正確。通過這樣的步驟针姿,系統(tǒng)在并不知道用戶密碼的明碼的情況下就可以確定用戶登錄系統(tǒng)的合法性袱吆。這不但可以避免用戶的密碼被具有系統(tǒng)管理員權(quán)限的用戶知道,而且還在一定程度上增加了密碼被破解的難度距淫。)

  • 防止抵賴(數(shù)字簽名)
    這需要一個第三方認證機構(gòu)绞绒。例如A寫了一個文件,認證機構(gòu)對此文件用MD5算法產(chǎn)生摘要信息并做好記錄榕暇。若以后A說這文件不是他寫的蓬衡,權(quán)威機構(gòu)只需對此文件重新產(chǎn)生摘要信息,然后跟記錄在冊的摘要信息進行比對彤枢,相同的話狰晚,就證明是A寫的了。這就是所謂的“數(shù)字簽名”缴啡。

MD5算法過程

對MD5算法簡要的敘述可以為:MD5以512位分組來處理輸入的信息壁晒,且每一分組又被劃分為16個32位子分組,經(jīng)過了一系列的處理后业栅,算法的輸出由四個32位分組組成秒咐,將這四個32位分組級聯(lián)后將生成一個128位散列值。

  • 填充
    如果輸入信息的長度(bit)對512求余的結(jié)果不等于448碘裕,就需要填充使得對512求余的結(jié)果等于448反镇。填充的方法是填充一個1和n個0。填充完后娘汞,信息的長度就為N*512+448(bit);
  • 記錄信息長度:用64位來存儲填充前信息長度夕玩。這64位加在第一步結(jié)果的后面你弦,這樣信息長度就變?yōu)镹512+448+64=(N+1)512位惊豺。 第
  • 裝入標準的幻數(shù)(四個整數(shù)):
    標準的幻數(shù)(物理順序)是
A=(01234567)16
B=(89ABCDEF)16
C=(FEDCBA98)16
D = (76543210)16
如果在程序中定義應(yīng)該是
A=0X67452301L
B=0XEFCDAB89L
C=0X98BADCFEL
D=0X10325476L 
  • 四輪循環(huán)運算:循環(huán)的次數(shù)是分組的個數(shù)(N+1)
    • 將每一512字節(jié)細分成16個小組,每個小組64位(8個字節(jié))
    • 先認識四個線性函數(shù)
(&是與,|是或,~是非,^是異或)  
F(X,Y,Z)=(X&Y)|((~X)&Z)  
G(X,Y,Z)=(X&Z)|(Y&(~Z))  
H(X,Y,Z)=X^Y^Z  
I(X,Y,Z)=Y^(X|(~Z))
- 設(shè)Mj表示消息的第j個子分組(從0到15)禽作,<<<s表示循環(huán)左移s位尸昧,則四種操作為:
FF(a,b,c,d,Mj,s,ti)
表示a=b+((a+F(b,c,d)+Mj+ti)<<<s)  
GG(a,b,c,d,Mj,s,ti)表示
a=b+((a+G(b,c,d)+Mj+ti)<<<s)  
HH(a,b,c,d,Mj,s,ti)
表示a=b+((a+H(b,c,d)+Mj+ti)<<<s)  
II(a,b,c,d,Mj,s,ti)
表示a=b+((a+I(b,c,d)+Mj+ti)<<<s)
- 四輪運算
第一輪
a=FF(a,b,c,d,M0,7,0xd76aa478)
b=FF(d,a,b,c,M1,12,0xe8c7b756)
c=FF(c,d,a,b,M2,17,0x242070db)
d=FF(b,c,d,a,M3,22,0xc1bdceee)
a=FF(a,b,c,d,M4,7,0xf57c0faf)
b=FF(d,a,b,c,M5,12,0x4787c62a)
c=FF(c,d,a,b,M6,17,0xa8304613)
d=FF(b,c,d,a,M7,22,0xfd469501)
a=FF(a,b,c,d,M8,7,0x698098d8)
b=FF(d,a,b,c,M9,12,0x8b44f7af)
c=FF(c,d,a,b,M10,17,0xffff5bb1)
d=FF(b,c,d,a,M11,22,0x895cd7be)
a=FF(a,b,c,d,M12,7,0x6b901122)
b=FF(d,a,b,c,M13,12,0xfd987193)
c=FF(c,d,a,b,M14,17,0xa679438e)
d=FF(b,c,d,a,M15,22,0x49b40821)
**第二輪**
a=GG(a,b,c,d,M1,5,0xf61e2562)
b=GG(d,a,b,c,M6,9,0xc040b340)
c=GG(c,d,a,b,M11,14,0x265e5a51)
d=GG(b,c,d,a,M0,20,0xe9b6c7aa)
a=GG(a,b,c,d,M5,5,0xd62f105d)
b=GG(d,a,b,c,M10,9,0x02441453)
c=GG(c,d,a,b,M15,14,0xd8a1e681)
d=GG(b,c,d,a,M4,20,0xe7d3fbc8)
a=GG(a,b,c,d,M9,5,0x21e1cde6)
b=GG(d,a,b,c,M14,9,0xc33707d6)
c=GG(c,d,a,b,M3,14,0xf4d50d87)
d=GG(b,c,d,a,M8,20,0x455a14ed)
a=GG(a,b,c,d,M13,5,0xa9e3e905)
b=GG(d,a,b,c,M2,9,0xfcefa3f8)
c=GG(c,d,a,b,M7,14,0x676f02d9)
d=GG(b,c,d,a,M12,20,0x8d2a4c8a)
**第三輪**
a=HH(a,b,c,d,M5,4,0xfffa3942)
b=HH(d,a,b,c,M8,11,0x8771f681)
c=HH(c,d,a,b,M11,16,0x6d9d6122)
d=HH(b,c,d,a,M14,23,0xfde5380c)
a=HH(a,b,c,d,M1,4,0xa4beea44)
b=HH(d,a,b,c,M4,11,0x4bdecfa9)
c=HH(c,d,a,b,M7,16,0xf6bb4b60)
d=HH(b,c,d,a,M10,23,0xbebfbc70)
a=HH(a,b,c,d,M13,4,0x289b7ec6)
b=HH(d,a,b,c,M0,11,0xeaa127fa)
c=HH(c,d,a,b,M3,16,0xd4ef3085)
d=HH(b,c,d,a,M6,23,0x04881d05)
a=HH(a,b,c,d,M9,4,0xd9d4d039)
b=HH(d,a,b,c,M12,11,0xe6db99e5)
c=HH(c,d,a,b,M15,16,0x1fa27cf8)
d=HH(b,c,d,a,M2,23,0xc4ac5665)*
*第四輪**
a=II(a,b,c,d,M0,6,0xf4292244)
b=II(d,a,b,c,M7,10,0x432aff97)
c=II(c,d,a,b,M14,15,0xab9423a7)
d=II(b,c,d,a,M5,21,0xfc93a039)
a=II(a,b,c,d,M12,6,0x655b59c3)
b=II(d,a,b,c,M3,10,0x8f0ccc92)
c=II(c,d,a,b,M10,15,0xffeff47d)
d=II(b,c,d,a,M1,21,0x85845dd1)
a=II(a,b,c,d,M8,6,0x6fa87e4f)
b=II(d,a,b,c,M15,10,0xfe2ce6e0)
c=II(c,d,a,b,M6,15,0xa3014314)
d=II(b,c,d,a,M13,21,0x4e0811a1)
a=II(a,b,c,d,M4,6,0xf7537e82)
b=II(d,a,b,c,M11,10,0xbd3af235)
c=II(c,d,a,b,M2,15,0x2ad7d2bb)
d=II(b,c,d,a,M9,21,0xeb86d391)
每輪循環(huán)后,將A旷偿,B烹俗,C,D分別加上a萍程,b幢妄,c,d茫负,然后進入下一循環(huán)蕉鸳。

代碼演示

/*
 * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
 * Digest Algorithm, as defined in RFC 1321.
 * Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
 * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
 * Distributed under the BSD License
 * See http://pajhome.org.uk/crypt/md5 for more info.
 */

/*
 * Configurable variables. You may need to tweak these to be compatible with
 * the server-side, but the defaults work in most cases.
 */
var hexcase = 1;  /* hex output format. 0 - lowercase; 1 - uppercase        */
var b64pad  = ""; /* base-64 pad character. "=" for strict RFC compliance   */
var chrsz   = 8;  /* bits per input character. 8 - ASCII; 16 - Unicode      */

/*
 * These are the functions you'll usually want to call
 * They take string arguments and return either hex or base-64 encoded strings
 */
function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}
function str_md5(s){ return binl2str(core_md5(str2binl(s), s.length * chrsz));}
function hex_hmac_md5(key, data) { return binl2hex(core_hmac_md5(key, data)); }
function str_hmac_md5(key, data) { return binl2str(core_hmac_md5(key, data)); }

/*
 * Calculate the MD5 of an array of little-endian words, and a bit length
 */
function core_md5(x, len)
{
  /* append padding */
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
    d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
    c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819);
    b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
    a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
    d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426);
    c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
    b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
    a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416);
    d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
    c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
    b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
    a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682);
    d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
    c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
    b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
    d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
    c = md5_gg(c, d, a, b, x[i+11], 14,  643717713);
    b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
    a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
    d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083);
    c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
    b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
    a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438);
    d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
    c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
    b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501);
    a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
    d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
    c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473);
    b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
    d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
    c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562);
    b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
    a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
    d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353);
    c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
    b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
    a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174);
    d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
    c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
    b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189);
    a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
    d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
    c = md5_hh(c, d, a, b, x[i+15], 16,  530742520);
    b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
    d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415);
    c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
    b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
    a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571);
    d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
    c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
    b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
    a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359);
    d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
    c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
    b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649);
    a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
    d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
    c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259);
    b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

/*
 * These functions implement the four basic operations the algorithm uses.
 */
function md5_cmn(q, a, b, x, s, t)
{
  return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b);
}
function md5_ff(a, b, c, d, x, s, t)
{
  return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t);
}
function md5_gg(a, b, c, d, x, s, t)
{
  return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t);
}
function md5_hh(a, b, c, d, x, s, t)
{
  return md5_cmn(b ^ c ^ d, a, b, x, s, t);
}
function md5_ii(a, b, c, d, x, s, t)
{
  return md5_cmn(c ^ (b | (~d)), a, b, x, s, t);
}

/*
 * Calculate the HMAC-MD5, of a key and some data
 */
function core_hmac_md5(key, data)
{
  var bkey = str2binl(key);
  if(bkey.length > 16) bkey = core_md5(bkey, key.length * chrsz);

  var ipad = Array(16), opad = Array(16);
  for(var i = 0; i < 16; i++)
  {
    ipad[i] = bkey[i] ^ 0x36363636;
    opad[i] = bkey[i] ^ 0x5C5C5C5C;
  }

  var hash = core_md5(ipad.concat(str2binl(data)), 512 + data.length * chrsz);
  return core_md5(opad.concat(hash), 512 + 128);
}

/*
 * Add integers, wrapping at 2^32. This uses 16-bit operations internally
 * to work around bugs in some JS interpreters.
 */
function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

/*
 * Bitwise rotate a 32-bit number to the left.
 */
function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

/*
 * Convert a string to an array of little-endian words
 * If chrsz is ASCII, characters >255 have their hi-byte silently ignored.
 */
function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

/*
 * Convert an array of little-endian words to a string
 */
function binl2str(bin)
{
  var str = "";
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < bin.length * 32; i += chrsz)
    str += String.fromCharCode((bin[i>>5] >>> (i % 32)) & mask);
  return str;
}

/*
 * Convert an array of little-endian words to a hex string.
 */
function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

String.prototype.trim = function(){return this.replace(/(^s*)|(s*$)/g, "");}

function md5(text) {
    return hex_md5(text.trim());
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市忍法,隨后出現(xiàn)的幾起案子潮尝,更是在濱河造成了極大的恐慌,老刑警劉巖饿序,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件勉失,死亡現(xiàn)場離奇詭異,居然都是意外死亡原探,警方通過查閱死者的電腦和手機乱凿,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來踢匣,“玉大人告匠,你說我怎么就攤上這事±牖#” “怎么了后专?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵,是天一觀的道長输莺。 經(jīng)常有香客問我戚哎,道長,這世上最難降的妖魔是什么嫂用? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任型凳,我火速辦了婚禮,結(jié)果婚禮上嘱函,老公的妹妹穿的比我還像新娘甘畅。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布疏唾。 她就那樣靜靜地躺著蓄氧,像睡著了一般。 火紅的嫁衣襯著肌膚如雪槐脏。 梳的紋絲不亂的頭發(fā)上喉童,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天,我揣著相機與錄音顿天,去河邊找鬼堂氯。 笑死,一個胖子當(dāng)著我的面吹牛牌废,可吹牛的內(nèi)容都是我干的咽白。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼畔规,長吁一口氣:“原來是場噩夢啊……” “哼局扶!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起叁扫,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤三妈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后莫绣,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體畴蒲,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年对室,在試婚紗的時候發(fā)現(xiàn)自己被綠了模燥。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡掩宜,死狀恐怖蔫骂,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情牺汤,我是刑警寧澤辽旋,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站檐迟,受9級特大地震影響补胚,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜追迟,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一溶其、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧敦间,春花似錦瓶逃、人聲如沸束铭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽纯露。三九已至,卻和暖如春代芜,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背浓利。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工挤庇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贷掖。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓嫡秕,卻偏偏與公主長得像,于是被迫代替她去往敵國和親苹威。 傳聞我的和親對象是個殘疾皇子昆咽,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容