java
public class SM3Util {
private static final int[] Tj = { 0x79cc4519, 0x7a879d8a };
private SM3Util() {
}
private static int rotateLeft(int x, int n, int k) {
return (x << n) | (x >>> k);
}
private static int p1(int X) {
return X ^ rotateLeft(X, 15, 17) ^ rotateLeft(X, 23, 9);
}
private static byte[] padding(byte[] message) {
int length = message.length;
long datalength = length << 3;
int l = length & 63;
int padd = l > 55 ? 128 - l : 64 - l;
byte[] paddArr = new byte[padd];
paddArr[0] = (byte) 0x80;
int k = padd - 8;
for (int i = 1; i < k; i++) {
paddArr[i] = 0x0;
}
for (int i = 0; i < 8; i++) {
paddArr[i + k] = (byte) ((datalength >>> ((7 - i) << 3)) & 0xff);
}
byte[] result = new byte[length + padd];
System.arraycopy(message, 0, result, 0, length);
System.arraycopy(paddArr, 0, result, length, padd);
return result;
}
public static byte[] hash(byte[] message) {
int[] IV = { 0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d,
0xb0fb0e4e };
long forlength = message.length >> 6;
byte[] handByte = new byte[64];
int[] groupbyA = new int[68];
for (int index = 0; index < forlength; index++) {
System.arraycopy(message, index << 6, handByte, 0, 64);
for (int i = 0; i < 64; i += 4) {
groupbyA[i >> 2] = (handByte[i] & 0xff) << 24 | (handByte[i + 1] & 0xff) << 16
| (handByte[i + 2] & 0xff) << 8 | handByte[i + 3] & 0xff;
}
int a = IV[0];
int b = IV[1];
int c = IV[2];
int d = IV[3];
int e = IV[4];
int f = IV[5];
int g = IV[6];
int h = IV[7];
int ss1;
int ss2;
int tt1;
int tt2;
int j = 0;
for (; j < 52; j++) {
groupbyA[j + 16] = p1(groupbyA[j] ^ groupbyA[j + 7] ^ rotateLeft(groupbyA[j + 13], 15, 17))
^ rotateLeft(groupbyA[j + 3], 7, 25) ^ groupbyA[j + 10];
ss1 = rotateLeft((rotateLeft(a, 12, 20) + e + rotateLeft(Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
ss2 = ss1 ^ rotateLeft(a, 12, 20);
if (j < 16) {
tt1 = (a ^ b ^ c) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
tt2 = (e ^ f ^ g) + h + ss1 + groupbyA[j];
} else {
tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];
}
d = c;
c = rotateLeft(b, 9, 23);
b = a;
a = tt1;
h = g;
g = rotateLeft(f, 19, 13);
f = e;
e = tt2 ^ rotateLeft(tt2, 9, 23) ^ rotateLeft(tt2, 17, 15);
}
for (; j < 64; j++) {
ss1 = rotateLeft((rotateLeft(a, 12, 20) + e + rotateLeft(Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
ss2 = ss1 ^ rotateLeft(a, 12, 20);
tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];
d = c;
c = rotateLeft(b, 9, 23);
b = a;
a = tt1;
h = g;
g = rotateLeft(f, 19, 13);
f = e;
e = tt2 ^ rotateLeft(tt2, 9, 23) ^ rotateLeft(tt2, 17, 15);
}
IV[0] ^= a;
IV[1] ^= b;
IV[2] ^= c;
IV[3] ^= d;
IV[4] ^= e;
IV[5] ^= f;
IV[6] ^= g;
IV[7] ^= h;
}
byte[] result = new byte[32];
for (int i = 0; i < 8; i++) {
intToByteArray(IV[i], result, i << 2);
}
return result;
}
private static void intToByteArray(int n, byte[] b, int offset) {
b[offset] = (byte) (n >>> 24);
b[offset + 1] = (byte) (n >>> 16);
b[offset + 2] = (byte) (n >>> 8);
b[offset + 3] = (byte) n;
}
public static String encryption(Object object) {
byte[] byteArray = null;
if (object instanceof Number) {
byteArray = object.toString().getBytes(StandardCharsets.UTF_8);
} else if (object instanceof File) {
try {
byteArray = Files.readAllBytes(((File) object).toPath());
} catch (IOException e) {
e.printStackTrace();
}
} else if (object instanceof byte[]) {
byteArray = (byte[]) object;
} else if (object instanceof String) {
byteArray = ((String) object).getBytes(StandardCharsets.UTF_8);
}
return encryption(byteArray);
}
public static String encryption(String byteArray) {
return encryption(byteArray.getBytes(StandardCharsets.UTF_8));
}
public static String encryption(byte[] byteArray) {
try {
if (byteArray != null) {
return ArrayUtils.bytesToHex(hash(padding(byteArray)));
}
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
public static void main(String[] args) {
System.err.println(SM3Util.encryption("1234567"));
}
}
TS
export class SM3Utils {
constructor() {
}
private static Tj: number[] = [0x79cc4519, 0x7a879d8a];
private static rotateLeft(x: number, n: number, k: number): number {
return (x << n) | (x >>> k);
}
private static p1(X: number): number {
return X ^ this.rotateLeft(X, 15, 17) ^ this.rotateLeft(X, 23, 9);
}
private static padding(message: Int8Array): Int8Array {
const length: number = message.length;
const datalength: bigint = BigInt(length) << BigInt(3);
const l: number = length & 63;
const padd: number = l > 55 ? 128 - l : 64 - l;
const paddArr: Int8Array = new Int8Array(padd);
paddArr[0] = 0x80;
const k: number = padd - 8;
for (let i = 1; i < k; i++) {
paddArr[i] = 0x0;
}
for (let i = 0; i < 8; i++) {
paddArr[i + k] = Number((datalength >> BigInt((7 - i) << 3)) & BigInt(0xff));
}
const result: Int8Array = new Int8Array(length + padd);
result.set(message);
result.set(paddArr, length);
return result;
}
public static hash(message: Int8Array): Int8Array {
const IV: number[] = [0x7380166f, 0x4914b2b9, 0x172442d7, 0xda8a0600, 0xa96f30bc, 0x163138aa, 0xe38dee4d, 0xb0fb0e4e];
const forlength: bigint = BigInt(message.length) >> BigInt(6);
const handByte: Int8Array = new Int8Array(64);
const groupbyA: number[] = new Array(68);
for (let index = 0n; index < forlength; index++) {
handByte.set(message.subarray(Number(index << BigInt(6)), Number(index << BigInt(6)) + 64));
for (let i = 0; i < 64; i += 4) {
groupbyA[i >> 2] = (handByte[i] & 0xff) << 24 | (handByte[i + 1] & 0xff) << 16
| (handByte[i + 2] & 0xff) << 8 | handByte[i + 3] & 0xff;
}
let a: number = IV[0];
let b: number = IV[1];
let c: number = IV[2];
let d: number = IV[3];
let e: number = IV[4];
let f: number = IV[5];
let g: number = IV[6];
let h: number = IV[7];
let ss1: number, ss2: number, tt1: number, tt2: number;
let j: number = 0;
for (; j < 52; j++) {
groupbyA[j + 16] = this.p1(groupbyA[j] ^ groupbyA[j + 7] ^ this.rotateLeft(groupbyA[j + 13], 15, 17)) ^ this.rotateLeft(groupbyA[j + 3], 7, 25) ^ groupbyA[j + 10];
ss1 = this.rotateLeft((this.rotateLeft(a, 12, 20) + e + this.rotateLeft(this.Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
ss2 = ss1 ^ this.rotateLeft(a, 12, 20);
if (j < 16) {
tt1 = (a ^ b ^ c) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
tt2 = (e ^ f ^ g) + h + ss1 + groupbyA[j];
} else {
tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];
}
d = c;
c = this.rotateLeft(b, 9, 23);
b = a;
a = tt1;
h = g;
g = this.rotateLeft(f, 19, 13);
f = e;
e = tt2 ^ this.rotateLeft(tt2, 9, 23) ^ this.rotateLeft(tt2, 17, 15);
}
for (; j < 64; j++) {
ss1 = this.rotateLeft((this.rotateLeft(a, 12, 20) + e + this.rotateLeft(this.Tj[j < 16 ? 0 : 1], j, 32 - j)), 7, 25);
ss2 = ss1 ^ this.rotateLeft(a, 12, 20);
tt1 = ((a & b) | (a & c) | (b & c)) + d + ss2 + (groupbyA[j] ^ groupbyA[j + 4]);
tt2 = ((e & f) | (~e & g)) + h + ss1 + groupbyA[j];
d = c;
c = this.rotateLeft(b, 9, 23);
b = a;
a = tt1;
h = g;
g = this.rotateLeft(f, 19, 13);
f = e;
e = tt2 ^ this.rotateLeft(tt2, 9, 23) ^ this.rotateLeft(tt2, 17, 15);
}
IV[0] ^= a;
IV[1] ^= b;
IV[2] ^= c;
IV[3] ^= d;
IV[4] ^= e;
IV[5] ^= f;
IV[6] ^= g;
IV[7] ^= h;
}
const result: Int8Array = new Int8Array(32);
for (let i = 0; i < 8; i++) {
this.intToByteArray(IV[i], result, i << 2);
}
return result;
}
private static intToByteArray(value: number, byteArray: Int8Array, offset: number) {
byteArray[offset] = (value >>> 24) & 0xff;
byteArray[offset + 1] = (value >>> 16) & 0xff;
byteArray[offset + 2] = (value >>> 8) & 0xff;
byteArray[offset + 3] = value & 0xff;
}
public static encryption(object: any): string {
let byteArray: Int8Array | null = null;
if (typeof object === 'number' || typeof object === 'string') {
byteArray = new Int8Array(new TextEncoder().encode(object.toString()));
} else if (object instanceof File) {
const reader = new FileReader();
reader.readAsArrayBuffer(object);
byteArray = new Int8Array(reader.result as ArrayBuffer);
} else if (Array.isArray(object) && object.every((el) => typeof el === 'number')) {
byteArray = new Int8Array(object);
}
if (byteArray) {
return ArrayUtils.bytesToHex(this.hash(this.padding(byteArray)));
}
return '';
}
}