Java实现的一个生成系统内唯一且无法被伪造的订单号的工具,基本思路是对long型自增的id加密解密,加密算法是AES,需要结合其他encode/
decode方法。
AESUtil
加密解密的工具类
import javax.crypto.BadPaddingException;
import javax.crypto.Cipher;
import javax.crypto.IllegalBlockSizeException;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
public class AESUtil {
private static final byte[] SECRET_KEY = "7975922666f6eb02".getBytes(StandardCharsets.UTF_8);
public static byte[] encrypt(byte[] plaintext) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY, "AES");
// 算法/模式/补码方式
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec);
return cipher.doFinal(plaintext);
}
public static byte[] decrypt(byte[] ciphertext) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
SecretKeySpec secretKeySpec = new SecretKeySpec(SECRET_KEY, "AES");
Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKeySpec);
return cipher.doFinal(ciphertext);
}
public static byte[] encryptId(long id) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
byte[] plaintext = new byte[8];
for(int i = 0;i < 8; ++i) {
plaintext[i] = (byte) ((id >> (7 - i) * 8) & 0xFF);
}
return encrypt(plaintext);
}
public static long decryptId(byte[] ciphertext) throws IllegalBlockSizeException, InvalidKeyException, BadPaddingException, NoSuchAlgorithmException, NoSuchPaddingException {
long id = 0;
byte[] plaintext = decrypt(ciphertext);
for(int i = 0;i < 8; ++i) {
id |= (long) (plaintext[i] & 0xFF) << (7 -i) * 8;
}
return id;
}
}
加密后得到的是byte数组,需要结合encode工具,下面是一个Base58编码工具
Base58Util
import java.math.BigInteger;
public class Base58Util {
private static final String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
private static final BigInteger BASE = BigInteger.valueOf(58L);
public Base58Util() {
}
public static String encode(byte[] input) {
BigInteger bi = new BigInteger(1, input);
StringBuffer s;
BigInteger mod;
for(s = new StringBuffer(); bi.compareTo(BASE) >= 0; bi = bi.subtract(mod).divide(BASE)) {
mod = bi.mod(BASE);
s.insert(0, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(mod.intValue()));
}
s.insert(0, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(bi.intValue()));
byte[] var7 = input;
int var4 = input.length;
for(int var5 = 0; var5 < var4; ++var5) {
byte anInput = var7[var5];
if (anInput != 0) {
break;
}
s.insert(0, "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(0));
}
return s.toString();
}
public static byte[] decode(String input) {
byte[] bytes = decodeToBigInteger(input).toByteArray();
boolean stripSignByte = bytes.length > 1 && bytes[0] == 0 && bytes[1] < 0;
int leadingZeros = 0;
for(int i = 0; input.charAt(i) == "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".charAt(0); ++i) {
++leadingZeros;
}
byte[] tmp = new byte[bytes.length - (stripSignByte ? 1 : 0) + leadingZeros];
System.arraycopy(bytes, stripSignByte ? 1 : 0, tmp, leadingZeros, tmp.length - leadingZeros);
return tmp;
}
public static BigInteger decodeToBigInteger(String input) {
BigInteger bi = BigInteger.valueOf(0L);
for(int i = input.length() - 1; i >= 0; --i) {
int alphaIndex = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz".indexOf(input.charAt(i));
if (alphaIndex == -1) {
throw new IllegalStateException("Illegal character " + input.charAt(i) + " at " + i);
}
bi = bi.add(BigInteger.valueOf((long)alphaIndex).multiply(BASE.pow(input.length() - 1 - i)));
}
return bi;
}
}