Das codierte Ergebnis ist so kurz wie möglich, idealerweise unter 4.000 Zeichen. Cache. < /p>
Eine saubere Java-Lösung, keine Abhängigkeiten von externen Werkzeugen oder Diensten. 13.000+ Zeichen mit Basis64url-kodierter Deflat. geschätzt! < /p>
Code: Select all
public class EncryptionUtil {
private static final String AES = "AES/ECB/PKCS5Padding";
private static final String SECRET = "secret";
private final SecretKey secretKey;
private final RefinementEncryptionConfig encryptionConfig;
public FilterEncryptionUtil(RefinementEncryptionConfig encryptionConfig) {
this.encryptionConfig = encryptionConfig;
this.secretKey = new SecretKeySpec(SECRET.getBytes(StandardCharsets.UTF_8), "AES");
}
public String generateEncryptedUrl(List refinements) {
String compactString = generateCompactRefinementString(refinements);
return encryptCompactString(compactString);
}
public String encryptCompactString(String compactString) {
try {
Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
byte[] encrypted = cipher.doFinal(compactString.getBytes(StandardCharsets.UTF_8));
return Base64.getUrlEncoder().withoutPadding().encodeToString(encrypted);
} catch (Exception e) {
throw new RuntimeException("Encryption failed", e);
}
}
private String generateCompactRefinementString(List refinements) {
Map navigationAliases = encryptionConfig.getEncryptIdentifiers();
StringBuilder buffer = new StringBuilder();
Map valueRefinements = new LinkedHashMap();
List rangeRefinements = new ArrayList();
for (Refinement r : refinements) {
String alias = navigationAliases.getOrDefault(r.getNavigationName(), r.getNavigationName());
if ("Range".equalsIgnoreCase(r.getType())) {
String rangeStr = alias + ":R:" + r.getLow() + "-" + r.getHigh();
rangeRefinements.add(rangeStr);
} else {
valueRefinements.computeIfAbsent(alias, k -> new ArrayList()).add(r.getValue());
}
}
if (!rangeRefinements.isEmpty()) {
buffer.append(String.join("#", rangeRefinements));
}
for (Map.Entry entry : valueRefinements.entrySet()) {
if (!buffer.isEmpty()) buffer.append("#");
String part = entry.getKey() + ":V:" + String.join("|", entry.getValue());
buffer.append(part);
}
return buffer.toString();
}
public List decodeEncryptedUrl(String encryptedBase64) {
try {
byte[] decoded = Base64.getUrlDecoder().decode(encryptedBase64);
Cipher cipher = Cipher.getInstance(AES);
cipher.init(Cipher.DECRYPT_MODE, secretKey);
byte[] decryptedBytes = cipher.doFinal(decoded);
String compactString = new String(decryptedBytes, StandardCharsets.UTF_8);
return parseCompactRefinementString(compactString);
} catch (Exception e) {
throw new RuntimeException("Decryption failed", e);
}
}
private List parseCompactRefinementString(String compactString) {
List refinements = new ArrayList();
Map aliasToNav = encryptionConfig.getDecryptIdentifiers();
String[] parts = compactString.split("#");
for (String part : parts) {
String[] section = part.split(":");
if (section.length < 3) continue;
String alias = section[0];
String type = section[1];
String data = section[2];
String navName = aliasToNav.getOrDefault(alias, alias);
if ("R".equals(type)) {
String[] range = data.split("-");
if (range.length == 2) {
Refinement r = new Refinement();
r.setType("Range");
r.setNavigationName(navName);
r.setLow(range[0]);
r.setHigh(range[1]);
refinements.add(r);
}
} else if ("V".equals(type)) {
String[] values = data.split("\\|");
for (String value : values) {
Refinement r = new Refinement();
r.setType("Value");
r.setNavigationName(navName);
r.setValue(value);
refinements.add(r);
}
}
}
return refinements;
}
}