{"id":154,"date":"2019-05-31T22:41:18","date_gmt":"2019-05-31T14:41:18","guid":{"rendered":"https:\/\/blog.indeex.club\/?p=154"},"modified":"2020-06-20T23:16:41","modified_gmt":"2020-06-20T15:16:41","slug":"tea%e5%8a%a0%e5%af%86%e7%ae%97%e6%b3%95","status":"publish","type":"post","link":"https:\/\/blog.indeex.club\/index.php\/2019\/05\/31\/tea%e5%8a%a0%e5%af%86%e7%ae%97%e6%b3%95\/","title":{"rendered":"TEA\u52a0\u5bc6\u7b97\u6cd5"},"content":{"rendered":"<p>\u52a0\u5bc6\u7b97\u6cd5\u7528\u5904\u6e10\u6e10\u591a\u4e86\u8d77\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528\u7b80\u5355\u7684\u52a0\u5bc6\u7b97\u6cd5\u5bf9JS\u52a0\u5bc6\/\u89e3\u5bc6\uff0c\u8fd9\u91cc\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u5fae\u52a0\u5bc6\u7b97\u6cd5\u3002<\/p>\n<p><strong>\u5fae\u52a0\u5bc6\u7b97\u6cd5\uff08TEA\uff09<\/strong>\u53ca\u5176\u76f8\u5173\u53d8\u79cd\uff08XTEA\uff0cBlock TEA\uff0cXXTEA\uff09 \u90fd\u662f\u5206\u7ec4\u52a0\u5bc6\u7b97\u6cd5\uff0c\u5b9e\u73b0\u4e5f\u6bd4\u8f83\u7b80\u5355\u3002<\/p>\n<p><img src=\"https:\/\/hungking.cc\/assets\/imgs\/indeex.cc\/TEA.png\" alt=\"TEA\u52a0\u5bc6\u7b97\u6cd5\" \/><\/p>\n<p>\u3000\u3000TEA \u7b97\u6cd5\u6700\u521d\u662f\u7531\u5251\u6865\u8ba1\u7b97\u673a\u5b9e\u9a8c\u5ba4\u7684 David Wheeler \u548c Roger Needham \u5728 1994 \u5e74\u8bbe\u8ba1\u7684\u3002\u8be5\u7b97\u6cd5\u4f7f\u7528 128 \u4f4d\u7684\u5bc6\u94a5\u4e3a 64 \u4f4d\u7684\u4fe1\u606f\u5757\u8fdb\u884c\u52a0\u5bc6\uff0c\u5b83\u9700\u8981\u8fdb\u884c 64 \u8f6e\u8fed\u4ee3\uff0c\u5c3d\u7ba1\u4f5c\u8005\u8ba4\u4e3a 32 \u8f6e\u5df2\u7ecf\u8db3\u591f\u4e86\u3002\u8be5\u7b97\u6cd5\u4f7f\u7528\u4e86\u4e00\u4e2a\u795e\u79d8\u5e38\u6570\u03b4\u4f5c\u4e3a\u500d\u6570\uff0c\u5b83\u6765\u6e90\u4e8e\u9ec4\u91d1\u6bd4\u7387\uff0c\u4ee5\u4fdd\u8bc1\u6bcf\u4e00\u8f6e\u52a0\u5bc6\u90fd\u4e0d\u76f8\u540c\u3002\u4f46\u03b4\u7684\u7cbe\u786e\u503c\u4f3c\u4e4e\u5e76\u4e0d\u91cd\u8981\uff0c\u8fd9\u91cc TEA \u628a\u5b83\u5b9a\u4e49\u4e3a \u03b4=\u300c(\u221a5 &#8211; 1)231\u300d\uff08\u4e5f\u5c31\u662f\u7a0b\u5e8f\u4e2d\u7684 0\u00d79E3779B9\uff09\u3002<\/p>\n<p>\u3000\u3000<br \/>\n\u3000\u3000\u4e4b\u540e TEA \u7b97\u6cd5\u88ab\u53d1\u73b0\u5b58\u5728\u7f3a\u9677\uff0c\u4f5c\u4e3a\u56de\u5e94\uff0c\u8bbe\u8ba1\u8005\u63d0\u51fa\u4e86\u4e00\u4e2a TEA \u7684\u5347\u7ea7\u7248\u672c\u2014\u2014XTEA\uff08\u6709\u65f6\u4e5f\u88ab\u79f0\u4e3a\u201ctean\u201d\uff09\u3002XTEA \u8ddf TEA \u4f7f\u7528\u4e86\u76f8\u540c\u7684\u7b80\u5355\u8fd0\u7b97\uff0c\u4f46\u5b83\u91c7\u7528\u4e86\u622a\u7136\u4e0d\u540c\u7684\u987a\u5e8f\uff0c\u4e3a\u4e86\u963b\u6b62\u5bc6\u94a5\u8868\u653b\u51fb\uff0c\u56db\u4e2a\u5b50\u5bc6\u94a5\uff08\u5728\u52a0\u5bc6\u8fc7\u7a0b\u4e2d\uff0c\u539f 128 \u4f4d\u7684\u5bc6\u94a5\u88ab\u62c6\u5206\u4e3a 4 \u4e2a 32 \u4f4d\u7684\u5b50\u5bc6\u94a5\uff09\u91c7\u7528\u4e86\u4e00\u79cd\u4e0d\u592a\u6b63\u89c4\u7684\u65b9\u5f0f\u8fdb\u884c\u6df7\u5408\uff0c\u4f46\u901f\u5ea6\u66f4\u6162\u4e86\u3002<br \/>\n\u3000\u3000<br \/>\n\u3000\u3000<br \/>\n   \u4ee5\u4e0b\u662f\u8fd9\u4e2a\u7b97\u6cd5\u7684ECMAScript\u5f53\u4e0b\u7248\u672c\u7684\u5b9e\u73b0\u8fc7\u7a0b\uff1a<\/p>\n<pre><code class=\"language-javascript line-numbers\">class Tea {\n\n    private static round: number = 32;\n    private static key: string = \"3A DA 75 21 DB E3 DB B3 62 B7 49 01 A5 C6 EA D5\";\n\n    public static teaEncrypt(enData: ByteArray): ByteArray {\n        enData.position = 0;\n\n        let len: number = Math.ceil(enData.length \/ 8);\n\n        let keyArr: any[] = this.getKey(this.key);\n\n        let keyBytes: ByteArray = new ByteArray();\n        keyBytes.position;\n        keyBytes.endian = Endian.LITTLE_ENDIAN;\n\n        for (let i = 0; i &lt; keyArr.length; i++) {\n            keyBytes.writeByte(keyArr[i]);\n        }\n\n        let resData: ByteArray = new ByteArray();\n        resData.position = 0;\n        resData.endian = Endian.LITTLE_ENDIAN;\n\n        let nData: ByteArray = new ByteArray();\n        nData.position = 0;\n        nData.endian = Endian.LITTLE_ENDIAN;\n\n\n        enData.position = 0;\n        for (let i: number = 0; i &lt; len; i++) {\n            let enBytes: ByteArray = new ByteArray();\n            enBytes.position = 0;\n            enBytes.endian = Endian.LITTLE_ENDIAN;\n\n            if (enData.bytesAvailable &gt;= 8) {\n                enData.readBytes(enBytes, 0, 8);\n                let encrypted: ByteArray = new ByteArray();\n                encrypted.position = 0;\n                encrypted.endian = Endian.LITTLE_ENDIAN;\n\n                let encryptencrypted = this.encrypt(enBytes, keyBytes);\n\n                resData.writeBytes(encrypted, 0, encrypted.length);\n                encrypted.clear();\n                encrypted = null;\n            } else {\n\n                enData.readBytes(nData, 0, enData.bytesAvailable);\n            }\n            enBytes.clear();\n        }\n\n        nData.position = 0;\n        if (nData.length &gt; 0) {\n\n            resData.writeBytes(nData, 0, nData.length);\n        }\n        keyBytes.clear();\n\n        return resData;\n        enData.clear();\n    }\n\n    public static teaDecrypt(decData: ByteArray): ByteArray {\n        decData.position = 0;\n        let len: number = Math.ceil(decData.length \/ 8);\n\n        let keyArr: any[] = this.getKey(this.key);\n\n        let keyBytes: ByteArray = new ByteArray();\n        keyBytes.position;\n        keyBytes.endian = Endian.LITTLE_ENDIAN;\n        \/\/\u5c06\u5bc6\u94a5\u5199\u5165\u7f13\u51b2\u533a  \n        for (let i = 0; i &lt; keyArr.length; i++) {\n            keyBytes.writeByte(keyArr[i]);\n        }\n\n        let resData: ByteArray = new ByteArray();\n        resData.position = 0;\n        resData.endian = Endian.LITTLE_ENDIAN;\n        decData.position = 0;\n        for (let i: number = 0; i &lt; len; i++) {\n            let decBytes: ByteArray = new ByteArray();\n            decBytes.position = 0;\n            decBytes.endian = Endian.LITTLE_ENDIAN;\n            if (decData.bytesAvailable &gt;= 8) {\n                decData.readBytes(decBytes, 0, 8);\n                let decrypted: ByteArray = new ByteArray();\n                decrypted.position = 0;\n                decrypted.endian = Endian.LITTLE_ENDIAN;\n\n                let decryptdecrypted = this.decrypt(decBytes, keyBytes);\n\n                resData.writeBytes(decrypted, 0, decrypted.length);\n                decrypted.clear();\n            } else {\n\n                var nData: ByteArray = new ByteArray();\n                nData.position = 0;\n                nData.endian = Endian.LITTLE_ENDIAN;\n                decData.readBytes(nData, 0, decData.bytesAvailable);\n            }\n        }\n        keyBytes.clear();\n        decData.clear();\n        trace(\"\u89e3\u5bc6\u540e\u6570\u636e&gt;&gt;&gt;&gt;\" + this.ByteArrayToLongArray(resData, false));\n        if (nData.length &gt; 0) {\n            nData.readBytes(resData, 0, nData.length);\n        }\n        trace(\"----&gt;\" + nData.length);\n        return resData;\n        resData.clear();\n    }\n\n\n    private static LongArrayToByteArray(data: any[], includeLength: Boolean): ByteArray {\n        let length: number = data.length;\n\n        let n: number = (length - 1) &lt;&lt; 2;\n        if (includeLength) {\n            let m: number = data[length - 1];\n            if ((m &lt; n - 3) || (m &gt; n)) {\n                return null;\n            }\n            n = m;\n        }\n\n        let result: ByteArray = new ByteArray();\n        result.endian = Endian.LITTLE_ENDIAN;\n        for (let i: number = 0; i &lt; length; i++) {\n            result.writeUnsignedInt(data[i]);\n        }\n        if (includeLength) {\n\n            result.length = n;\n            return result;\n        } else {\n            return result;\n        }\n    }\n\n    private static ByteArrayToLongArray(data: ByteArray, includeLength: Boolean): any[] {\n        let length: number = data.length;\n        let n: number = length &gt;&gt; 2;\n        if (length % 4 &gt; 0) {\n            n++;\n            data.length += (4 - (length % 4));\n        }\n        data.endian = Endian.LITTLE_ENDIAN;\n        data.position = 0;\n        let result: any[] = [];\n        for (let i: number = 0; i &lt; n; i++) {\n            result[i] = data.readUnsignedInt();\n        }\n        if (includeLength) {\n            result[n] = length;\n        }\n        data.length = length;\n        return result;\n    }\n\n    private static encrypt(data: ByteArray, key: ByteArray): ByteArray {\n\n        if (data.length == 0) {\n            return new ByteArray();\n        }\n        let v: any[] = this.ByteArrayToLongArray(data, false);\n        let k: any[] = [987395361, 3689143219, 1656178945, 2781276885];\n        if (k.length &lt; 4) {\n            k.length = 4;\n        }\n        let n: number = v.length - 1;\n        let y: number = v[0];\n        let z: number = v[1];\n\n        let a: number = k[0];\n        let b: number = k[1];\n        let c: number = k[2];\n        let d: number = k[3];\n        let delta = 0x9E3779B9;\/* (sqrt(5)-1)\/2*2^32 *\/\n        let sum: number = 0;\n\n        for (let i: number = 0; i &lt; this.round; i++) {\n            sum += delta;\n            y += ((z &lt;&lt; 4) + a) ^ (z + sum) ^ ((z &gt;&gt;&gt; 5) + b);\n            z += ((y &lt;&lt; 4) + c) ^ (y + sum) ^ ((y &gt;&gt;&gt; 5) + d);\/* end cycle *\/\n        }\n        v[0] = y;\n        v[1] = z;\n\n        return this.LongArrayToByteArray(v, false);\n    }\n\n    private static decrypt(data: ByteArray, key: ByteArray): ByteArray {\n        if (data.length == 0) {\n            return new ByteArray();\n        }\n        let v: any[] = this.ByteArrayToLongArray(data, false);\n        let k: any[] = [987395361, 3689143219, 1656178945, 2781276885];\/\/\u5bc6\u94a5\u5199\u6b7b  \n        if (k.length &lt; 4) {\n            k.length = 4;\n        }\n        let n: number = v.length - 1;\n        let y: number = v[0];\n        let z: number = v[1];\n\n        let a: number = k[0];\n        let b: number = k[1];\n        let c: number = k[2];\n        let d: number = k[3];\n        let delta = 0x9E3779B9;\/* (sqrt(5)-1)\/2*2^32 *\/\n        let sum: number = 0xE3779B90;\n\n        if (this.round == 32) {\n            sum = 0xC6EF3720;\/\/delta &lt;&lt; 5 \n        } else if (this.round == 16) {\n            sum = 0xE3779B90;\n        }\n\n        for (let i: number = 0; i &lt; this.round; i++) {\n            z -= ((y &lt;&lt; 4) + c) ^ (y + sum) ^ ((y &gt;&gt;&gt; 5) + d);\n            y -= ((z &lt;&lt; 4) + a) ^ (z + sum) ^ ((z &gt;&gt;&gt; 5) + b);\n            sum -= delta;\n        }\n        v[0] = y;\n        v[1] = z;\n        return this.LongArrayToByteArray(v, false);\n    }\n    private static getKey(keyStr: string): any[] {\n        let key: string = keyStr;\n        let arr: any[] = new Array();\n        let res: any[] = new Array();\n        let target: any[] = new Array();\n        arr = key.split(\" \");\n        let curStr: string = \"\";\n        let len: number = arr.length;\n        for (let i: number = 0; i &lt; arr.length; i++) {\n            let newArr: any[] = new Array();\n            curStr = arr[i];\n\n            for (let j: number = 0; j &lt; 2; j++) {\n                let char: string = curStr.charAt(j);\n                newArr.push(char);\n            }\n            target.push(newArr);\n        }\n        for (let i = 0; i &lt; target.length; i++) {\n            let a: number = this.isNumber(target[i][0]);\n            let b: number = this.isNumber(target[i][1]);\n            let resNum: number = a * 16 + b;\n            res.push(resNum);\n        }\n        return res;\n    }\n    private static isNumber(char: string): number {\n        let arr: any[] = [\"0\", \"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\"];\n        for (let i: number = 0; i &lt; arr.length; i++) {\n            if (char == arr[i]) {\n                return Number(char);\n                break;\n            }\n        }\n        let id: number = 0;\n        switch (char) {\n            case \"A\":\n                id = 10;\n                break;\n            case \"B\":\n                id = 11;\n                break;\n            case \"C\":\n                id = 12;\n                break;\n            case \"D\":\n                id = 13;\n                break;\n            case \"E\":\n                id = 14;\n                break;\n            case \"F\":\n                id = 15;\n                break;\n            default:\n                break;\n        }\n        return id;\n    }\n    private static intToHexChar(index: number): string {\n        let hex: string[] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];\n        return hex[index];\n    }\n    private static intToHexString(arr: string[]): string {\n        let myStr: string = \"\";\n        for (let i: number = 0; i &lt; arr.length; ++i) {\n            let t: any = arr[i];\n            let a: number = Math.floor(t \/ 16);\n            let b: number = Math.floor(t % 16);\n            myStr += this.intToHexChar(a);\n            myStr += this.intToHexChar(b);\n            myStr += \" \";\n        }\n        return myStr;\n    }\n}\n\n\nfunction trace(msg: any): void {\n    console.log(msg);\n}\n<\/code><\/pre>\n<p>ByteArray\u548cEndian\u53ef\u4ee5\u81ea\u5df1\u5b9e\u73b0\uff0c\u8fd9\u91cc\u4e0d\u5728\u8d58\u8ff0\u3002<\/p>\n\n<p>code enjoy! &#x1f9d0;&#x1f9d0;&#x1f9d0;<\/p>\n<p>\u4f5c\u8005\uff1aindeex<\/p>\n<p>\u94fe\u63a5\uff1a<a class=\"wp-editor-md-post-content-link\" href=\"https:\/\/indeex.cc\/\">https:\/\/indeex.cc<\/a><\/p>\n<p>\u8457\u4f5c\u6743\u5f52\u4f5c\u8005\u6240\u6709\u3002\u5546\u4e1a\u8f6c\u8f7d\u8bf7\u8054\u7cfb\u4f5c\u8005\u83b7\u5f97\u6388\u6743\uff0c\u975e\u5546\u4e1a\u8f6c\u8f7d\u8bf7\u6ce8\u660e\u51fa\u5904\u3002<\/p>\n<hr \/>\n","protected":false},"excerpt":{"rendered":"<p>\u52a0\u5bc6\u7b97\u6cd5\u7528\u5904\u6e10\u6e10\u591a\u4e86\u8d77\u6765\uff0c\u53ef\u4ee5\u4f7f\u7528\u7b80\u5355\u7684\u52a0\u5bc6\u7b97\u6cd5\u5bf9JS\u52a0\u5bc6\/\u89e3\u5bc6\uff0c\u8fd9\u91cc\u5b9e\u73b0\u4e00\u4e2a\u7b80\u5355\u7684\u5fae\u52a0\u5bc6\u7b97\u6cd5\u3002 \u5fae<a href=\"https:\/\/blog.indeex.club\/index.php\/2019\/05\/31\/tea%e5%8a%a0%e5%af%86%e7%ae%97%e6%b3%95\/\" class=\"read-more\">Read More<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[3],"tags":[4],"_links":{"self":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts\/154"}],"collection":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/comments?post=154"}],"version-history":[{"count":1,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts\/154\/revisions"}],"predecessor-version":[{"id":161,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/posts\/154\/revisions\/161"}],"wp:attachment":[{"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/media?parent=154"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/categories?post=154"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.indeex.club\/index.php\/wp-json\/wp\/v2\/tags?post=154"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}