Created
October 30, 2021 06:21
-
-
Save maxchang3/dfb74bcc999ce9f3cc8860f04afc67a5 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// use (16 chars of) 'password' to encrypt 'plaintext' | |
function encrypt(plaintext, password) { | |
var v = new Array(2), k = new Array(4), s = "", i; | |
plaintext = escape(plaintext); // use escape() so only have single-byte chars to encode | |
// build key directly from 1st 16 chars of password | |
for (var i=0; i<4; i++) | |
k[i] = Str4ToLong(password.slice(i*4,(i+1)*4)); | |
for (i=0; i<plaintext.length; i+=8) { // encode plaintext into s in 64-bit (8 char) blocks | |
v[0] = Str4ToLong(plaintext.slice(i,i+4)); // ... note this is 'electronic codebook' mode | |
v[1] = Str4ToLong(plaintext.slice(i+4,i+8)); | |
console.log(v) | |
code(v, k); | |
console.log(v) | |
console.log(LongToBase16(v[0]) , LongToBase16(v[1])) | |
// console.log(plaintext.slice(i,i+4),plaintext.slice(i+4,i+8)) | |
// console.log(LongToBase16(v[0]),LongToBase16(v[1])) | |
s += LongToBase16(v[0]) + LongToBase16(v[1]); | |
//s += LongToStr4(v[0]) + LongToStr4(v[1]); | |
} | |
return escCtrlCh(s); | |
} | |
function LongToBase16(long) { | |
let base16 = ''; | |
for (let i = 0x3;i >= 0x0 ;i--) { | |
let v = (long >> 0x8 *i & 0xff).toString(0x10); | |
if (parseInt('0x' + v) <= 0xf) v = '0' + v; | |
base16 += v; | |
} | |
return base16; | |
} | |
function Base16ToLong(base16) { | |
let long = 0x0; | |
for (let i = 0; i < 8; i += 2) { | |
let v = parseInt('0x' + (base16).slice(i, i + 2)); | |
long = (long << 0x8) + v; | |
} | |
return long; | |
} | |
// use (16 chars of) 'password' to decrypt 'ciphertext' with xTEA | |
function decrypt(ciphertext, password) { | |
var v = new Array(2), k = new Array(4), s = "", i; | |
for (var i=0; i<4; i++) k[i] = Str4ToLong(password.slice(i*4,(i+1)*4)); | |
ciphertext = unescCtrlCh(ciphertext); | |
for (i=0; i<ciphertext.length; i+=16) { // decode ciphertext into s in 64-bit (8 char) blocks | |
v[0] = Base16ToLong(ciphertext.slice(i,i+8)) ; | |
v[1] = Base16ToLong(ciphertext.slice(i+8,i+16)) ; | |
console.log(v) | |
decode(v, k); | |
console.log(v) | |
s += LongToStr4(v[0]) + LongToStr4(v[1]); | |
} | |
//LongToBase16(Base16ToLong('d7a18d1f') - 17179869184) | |
//LongToBase16(Base16ToLong('d7a18d1f') +4294967296) | |
// strip trailing null chars resulting from filling 4-char blocks: | |
s = s.replace(/\0+$/, ''); | |
return unescape(s); | |
} | |
function code(v, k) { | |
// Extended TEA: this is the 1997 revised version of Needham & Wheeler's algorithm | |
// params: v[2] 64-bit value block; k[4] 128-bit key | |
var y = v[0], z = v[1]; | |
var delta = 0x9E3779B9, limit = delta*32, sum = 0; | |
while (sum != limit) { | |
y += (z<<4 ^ z>>>5)+z ^ sum+k[sum & 3]; | |
sum += delta; | |
z += (y<<4 ^ y>>>5)+y ^ sum+k[sum>>>11 & 3]; | |
// note: unsigned right-shift '>>>' is used in place of original '>>', due to lack | |
// of 'unsigned' type declaration in JavaScript (thanks to Karsten Kraus for this) | |
} | |
v[0] = y; v[1] = z; | |
} | |
function decode(v, k) { | |
var y = v[0], z = v[1]; | |
var delta = 0x9E3779B9, sum = delta*32; | |
while (sum != 0) { | |
z -= (y<<4 ^ y>>>5)+y ^ sum+k[sum>>>11 & 3]; | |
sum -= delta; | |
y -= (z<<4 ^ z>>>5)+z ^ sum+k[sum & 3]; | |
} | |
v[0] = y; v[1] = z; | |
} | |
// supporting functions | |
function Str4ToLong(s) { // convert 4 chars of s to a numeric long | |
var v = 0; | |
for (var i=0; i<4; i++) v |= s.charCodeAt(i) << i*8; | |
return isNaN(v) ? 0 : v; | |
} | |
function LongToStr4(v) { // convert a numeric long to 4 char string | |
var s = String.fromCharCode(v & 0xFF, v>>8 & 0xFF, v>>16 & 0xFF, v>>24 & 0xFF); | |
return s; | |
} | |
function escCtrlCh(str) { // escape control chars which might cause problems with encrypted texts | |
return str.replace(/[\0\t\n\v\f\r\xa0'"!]/g, function(c) { return '!' + c.charCodeAt(0) + '!'; }); | |
} | |
function unescCtrlCh(str) { // unescape potentially problematic nulls and control characters | |
return str.replace(/!\d\d?\d?!/g, function(c) { return String.fromCharCode(c.slice(1,-1)); }); | |
} | |
// let enc = encrypt('123aaaa','123aaaa') | |
// console.log(enc) | |
// console.log(decrypt(enc,'123aaaa')) | |
cipher ='6fbde674819a59bfa12092565b4ca2a7a11dc670c678681daf4afb6704b82f0c' | |
pwd ='1356853149054377' | |
plaintext = decrypt(cipher,pwd) | |
console.log(plaintext) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment