45 lines
1.8 KiB
Java
45 lines
1.8 KiB
Java
package com.baiyue.common.event;
|
|
|
|
import java.util.Locale;
|
|
|
|
/** Canonical physical container number used by cross-region business facts. */
|
|
public final class ContainerNumbers {
|
|
private static final int[] LETTER_VALUES = {
|
|
10, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 23, 24,
|
|
25, 26, 27, 28, 29, 30, 31, 32, 34, 35, 36, 37, 38
|
|
};
|
|
|
|
private ContainerNumbers() { }
|
|
|
|
public static String normalizeRequired(String value) {
|
|
if (value == null || value.isBlank()) {
|
|
throw new IllegalArgumentException("containerNo is required");
|
|
}
|
|
StringBuilder compact = new StringBuilder(value.length());
|
|
value.codePoints().filter(codePoint -> !Character.isWhitespace(codePoint)
|
|
&& !Character.isSpaceChar(codePoint)).forEach(compact::appendCodePoint);
|
|
String normalized = compact.toString().toUpperCase(Locale.ROOT);
|
|
if (!normalized.matches("[A-Z]{3}[UJZ][0-9]{7}")) {
|
|
throw new IllegalArgumentException("containerNo must comply with ISO 6346");
|
|
}
|
|
int sum = 0;
|
|
for (int index = 0; index < 10; index++) {
|
|
char current = normalized.charAt(index);
|
|
int number = Character.isDigit(current) ? current - '0' : LETTER_VALUES[current - 'A'];
|
|
sum += number * (1 << index);
|
|
}
|
|
if (normalized.charAt(10) - '0' != sum % 11 % 10) {
|
|
throw new IllegalArgumentException("containerNo must comply with ISO 6346 check digit");
|
|
}
|
|
return normalized;
|
|
}
|
|
|
|
public static String requireCanonical(String value) {
|
|
String normalized = normalizeRequired(value);
|
|
if (!normalized.equals(value)) {
|
|
throw new IllegalArgumentException("containerNo must be normalized");
|
|
}
|
|
return normalized;
|
|
}
|
|
}
|