Files
SHiNE-server/SHiNE-server/shine-server-db/src/main/java/shine/db/KeyEncodingUtil.java
T

116 lines
3.4 KiB
Java

package shine.db;
import java.util.Base64;
/**
* Нормализация ключей из разных storage-слоёв к каноническому Base64(32).
*/
public final class KeyEncodingUtil {
private static final String BASE58_ALPHABET =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
private static final int[] BASE58_INDEXES = new int[128];
static {
for (int i = 0; i < BASE58_INDEXES.length; i++) {
BASE58_INDEXES[i] = -1;
}
for (int i = 0; i < BASE58_ALPHABET.length(); i++) {
BASE58_INDEXES[BASE58_ALPHABET.charAt(i)] = i;
}
}
private KeyEncodingUtil() {}
public static String normalizeKeyToBase64_32(String rawKey) {
if (rawKey == null) {
return null;
}
String value = rawKey.trim();
if (value.isEmpty()) {
return value;
}
byte[] asBase64 = tryDecodeBase64_32(value);
if (asBase64 != null) {
return Base64.getEncoder().encodeToString(asBase64);
}
byte[] asBase58 = tryDecodeBase58_32(value);
if (asBase58 != null) {
return Base64.getEncoder().encodeToString(asBase58);
}
return value;
}
private static byte[] tryDecodeBase64_32(String value) {
try {
byte[] decoded = Base64.getDecoder().decode(value);
return decoded.length == 32 ? decoded : null;
} catch (IllegalArgumentException ignore) {
return null;
}
}
private static byte[] tryDecodeBase58_32(String value) {
byte[] decoded = decodeBase58(value);
return decoded.length == 32 ? decoded : null;
}
private static byte[] decodeBase58(String input) {
if (input.isEmpty()) {
return new byte[0];
}
byte[] input58 = new byte[input.length()];
for (int i = 0; i < input.length(); i++) {
char c = input.charAt(i);
if (c >= BASE58_INDEXES.length || BASE58_INDEXES[c] < 0) {
return new byte[0];
}
input58[i] = (byte) BASE58_INDEXES[c];
}
int zeros = 0;
while (zeros < input58.length && input58[zeros] == 0) {
zeros++;
}
byte[] decoded = new byte[input.length()];
int outputStart = decoded.length;
int inputStart = zeros;
while (inputStart < input58.length) {
int mod = divmod256(input58, inputStart);
if (input58[inputStart] == 0) {
inputStart++;
}
decoded[--outputStart] = (byte) mod;
}
while (outputStart < decoded.length && decoded[outputStart] == 0) {
outputStart++;
}
byte[] result = new byte[decoded.length - outputStart + zeros];
for (int i = 0; i < zeros; i++) {
result[i] = 0;
}
System.arraycopy(decoded, outputStart, result, zeros, decoded.length - outputStart);
return result;
}
private static int divmod256(byte[] number58, int startAt) {
int remainder = 0;
for (int i = startAt; i < number58.length; i++) {
int digit58 = number58[i] & 0xFF;
int temp = remainder * 58 + digit58;
number58[i] = (byte) (temp / 256);
remainder = temp % 256;
}
return remainder;
}
}