SHA256
116 lines
3.4 KiB
Java
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;
|
|
}
|
|
}
|