package com.cscn; /** * 辅助工具:装载/存储、位运算、线性变换、打印等。 */ public final class Zuc256Util { private Zuc256Util() {} /** 辅助方法:将字节数组转换为32位整数 */ public static int getU32(byte[] p, int offset) { return ((p[offset] & 0xFF) << 24) | ((p[offset + 1] & 0xFF) << 16) | ((p[offset + 2] & 0xFF) << 8) | (p[offset + 3] & 0xFF); } /** 辅助方法:将32位整数转换为字节数组 */ public static void putU32(byte[] p, int offset, int v) { p[offset] = (byte) (v >> 24); p[offset + 1] = (byte) (v >> 16); p[offset + 2] = (byte) (v >> 8); p[offset + 3] = (byte) v; } // === 31/32 位运算 === /** 31位加法 */ public static int add31(int a, int b) { long sum = (long)a + b; return (int) ((sum & 0x7FFFFFFF) + (sum >> 31)); } /** 31位旋转 */ public static int rot31(int a, int k) { return ((a << k) | (a >>> (31 - k))) & 0x7FFFFFFF; } /** 32位旋转 */ public static int rot32(int a, int k) { return (a << k) | (a >>> (32 - k)); } /** * L1函数 */ public static int L1(int x) { return x ^ rot32(x, 2) ^ rot32(x, 10) ^ rot32(x, 18) ^ rot32(x, 24); } /** * L2函数 */ public static int L2(int x) { return x ^ rot32(x, 8) ^ rot32(x, 14) ^ rot32(x, 22) ^ rot32(x, 30); } /** 创建31位无符号整数 */ public static int makeU31(int a, int b, int c, int d) { return (((a & 0xFF) << 23) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | (d & 0xFF)) & 0x7FFFFFFF; } /** 创建32位无符号整数 */ public static int makeU32(int a, int b, int c, int d) { return ((a & 0xFF) << 24) | ((b & 0xFF) << 16) | ((c & 0xFF) << 8) | (d & 0xFF); } /** 提取IV */ public static void extractIv(byte[] input25Byte, byte[] output23Byte) { if (input25Byte == null || output23Byte == null) return; // 复制前17字节 System.arraycopy(input25Byte, 0, output23Byte, 0, 17); // 处理剩余8字节 byte[] src = new byte[8]; for (int i = 0; i < 8; i++) { src[i] = (byte) (input25Byte[17 + i] & 0x3F); } output23Byte[17] = (byte) ((src[0] << 2) | (src[1] >>> 4)); output23Byte[18] = (byte) (((src[1] & 0x0F) << 4) | (src[2] >>> 2)); output23Byte[19] = (byte) (((src[2] & 0x03) << 6) | src[3]); output23Byte[20] = (byte) ((src[4] << 2) | (src[5] >>> 4)); output23Byte[21] = (byte) (((src[5] & 0x0F) << 4) | (src[6] >>> 2)); output23Byte[22] = (byte) (((src[6] & 0x03) << 6) | src[7]); } /** 打印十六进制(调试用,TODO 生产/JC 环境可移除) */ public static void printHex(String label, byte[] data, int len) { System.out.print(label + ": "); for (int i = 0; i < len; i++) { System.out.printf("%02x ", data[i] & 0xFF); } System.out.println(); } }