[LayaAirIDE 1.0]ts加密md5码封装

tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es6",
"sourceMap": true
},
"exclude": [
"node_modules"
]
}

test:
let str = Md5.Instance.get_md5("123456");
console.log(str)

//len:32
//e10adc3949ba59abbe56e057f20f883e
md5.ts
class Md5
{
private static _inst:Md5;
public static get Instance():Md5
{
return this._inst ||(this._inst = new Md5());
}
public get_md5(str:string):string
{
return this.md5(str);
}
split(target: string | any[], step: number, markString: boolean = typeof target === "string") {
if (typeof target === "string") target = target.split("");

let result: any[] = target.map(
(_, index: number) =>
index % step === 0
? Array.from(Array(step).keys()).map((x: number) => target[index + x])
: []
)
.filter((x: any[]) => x.length > 0);

if (markString) result = result.map((x: any[]) => x.join(""))

return result;
}
padding(str: string | any[], length: number, char: string, tail: boolean = true, isArray: boolean = Array.isArray(str)) {
let arr;
if (Array.isArray(str)) {
arr = str;
} else {
arr = str.split("");
}
const paddingStr: any[] = this.range(length - str.length).map(() => char);
const result = tail ? arr.concat(paddingStr) : paddingStr.concat(arr);
return isArray ? result : result.join("");
}
little_endian(charCode: number) {
return this.split(this.padding(charCode.toString(16), 8, "0", false), 2).reverse().join("");
}

range(...args: number[]) {
const start: number = args.length === 1 ? 0 : args[0];
const end: number = args.length === 2 ? args[1] : args[0] - 1;

return Array.from(Array(end - start + 1).keys()).map((x: number) => x + start);
}

to_binary(code: number, bit: number = 8, max: number = Math.pow(2, bit) - 1) {
if (code < 0) throw new Error("code should be greater than: 0");
if (code > max) throw new Error("code should be less than: " + max);
return this.padding(code.toString(2), bit, "0", false);
}

to_hex(code: number, bit: number = 8, max: number = Math.pow(16, bit) - 1) {
if (code < 0) throw new Error("code should be greater than: 0");
if (code > max) throw new Error("code should be less than: " + max);
return this.padding(code.toString(16), bit, "0", false);
}

to_code(str: string) {
if (str.substr(0, 2).toLowerCase() === "0b") return parseInt(str.substr(2, 8), 2);
if (str.substr(0, 2).toLowerCase() === "0x") return parseInt(str.substr(2, 8), 16);
}

utf16_to_utf8(str: string) {
return str.split("").map((char: string) => this.utf8_encode(char)).join("");
}

utf8_encode(char: string) {
let utftext = "";
const c = char.charCodeAt(0);
if (c < 128) {
utftext += String.fromCharCode(c);
} else if ((c > 127) && (c < 2048)) {
utftext += String.fromCharCode((c >> 6) | 0b11000000);
utftext += String.fromCharCode((c & 0b00111111) | 0b10000000);
} else {
utftext += String.fromCharCode((c >> 12) | 0b11100000);
utftext += String.fromCharCode(((c >> 6) & 0b00111111) | 0b10000000);
utftext += String.fromCharCode((c & 0b00111111) | 0b10000000);
}

return utftext;
}

uint_add(...args: number[]) {
const t = Uint32Array.from([0]);
const x = Uint32Array.from(args);
x.forEach(n => t[0] = t[0] + n);
return t[0];
}

loop_shift_left(n: number, bits: number) {
return (n << bits) | (n >>> (32 - bits));
}

A = 0x67452301;
B = 0xefcdab89;
C = 0x98badcfe;
D = 0x10325476;

F(b: number, c: number, d: number) {
return (b & c) | (~b & d);
}

G(b: number, c: number, d: number) {
return (b & d) | (c & ~d);
}

H(b: number, c: number, d: number) {
return b ^ c ^ d;
}

I(b: number, c: number, d: number) {
return c ^ (b | ~d)
}

S = [
7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22,
5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20,
4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23,
6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21
]

T(i: number) {
return Math.floor(Math.pow(2, 32) * Math.abs(Math.sin(i + 1)));
}

x_index(i: number) {
if (i >= 0 && i <= 15) return i;
if (i >= 16 && i <= 31) return (5 * i + 1) % 16;
if (i >= 32 && i <= 47) return (3 * i + 5) % 16;
if (i >= 48 && i <= 63) return (7 * i) % 16;
return 0;
}

wrap(m: any) {
return (a: number, b: number, c: number, d: number, x: number, s: number, t: number) => {
// 循环左移
return this.uint_add(this.loop_shift_left(this.uint_add(a, m(b, c, d), x, t), s), b);
};
}

porcess_message(str: string) {
const length = str.length;
const length_of_zero = Math.ceil(length / 64) * 64 - length - 8 - 1;
str += String.fromCharCode(0b10000000);
const strArray = this.padding(str.split(""), length + 1 + length_of_zero, String.fromCharCode(0));

const tail = this.split(this.padding(this.to_binary(length * 8 % Math.pow(2, 64)), 64, "0"), 8).map(x => parseInt(x, 2));
const head = (strArray as any[]).map(x => x.charCodeAt(0));
return Uint32Array.from(
this.split(head.concat(tail), 4)
.map(x =>
x.map((t: number) => this.padding(t.toString(16), 2, "0", false)).join("")
)
.map(x => parseInt(x, 16))
.map(x => parseInt(this.little_endian(x), 16))
)
}

fghi(i: number) {
if (i >= 0 && i <= 15) return this.F;
if (i >= 16 && i <= 31) return this.G;
if (i >= 32 && i <= 47) return this.H;
if (i >= 48 && i <= 63) return this.I;
}

fghi_wrapped(i: number) {
return this.wrap(this.fghi(i));
}

//------------------------------------------------
md5(str: string) {
str = this.utf16_to_utf8(str);
const uint32_array = this.porcess_message(str);
const result = Uint32Array.from([this.A, this.B, this.C, this.D]);
const chunks = this.split(Array.from(uint32_array), 16);
for (const chunk of chunks) {
const a = result[0];
const b = result[1];
const c = result[2];
const d = result[3];

for (let i = 0; i < 64; i++) {
result[(4 - i % 4) % 4] = this.fghi_wrapped(i)(result[(4 - i % 4) % 4], result[((4 - i % 4) + 1) % 4], result[((4 - i % 4) + 2) % 4], result[((4 - i % 4) + 3) % 4], chunk[this.x_index(i)], this.S[i], this.T(i))
}

result[0] = a + result[0];
result[1] = b + result[1];
result[2] = c + result[2];
result[3] = d + result[3];

}
return Array.from(result).map(x => this.little_endian(x)).join("").toLowerCase();
}
}

已邀请:

bpmf_d

赞同来自:

感谢分享~

Chiuan

赞同来自:

谢谢分享。

要回复问题请先

商务合作
商务合作