Base64Utils.java
package net.hostsharing.hsadminng.hash;
import lombok.experimental.UtilityClass;
@UtilityClass
public class Base64Utils {
public static boolean isBase64(String str) {
if (str == null || str.isEmpty()) {
return false;
}
// Base64 encoding requires at least 2 characters to represent any meaningful data
if (str.length() < 2) {
return false;
}
if (str.contains("=")) {
return isValidPaddedBase64(str);
} else {
return isValidUnpaddedBase64(str);
}
}
private static boolean isValidPaddedBase64(final String str) {
// if it has padding, the length must be divisible by 4
if (str.length() % 4 != 0) {
return false;
}
// check padded Base64 format - padding can only be at the end
if (!str.matches("^[A-Za-z0-9+/]+={1,2}$")) {
return false;
}
// ensure padding is only at the end
int paddingStart = str.indexOf('=');
return paddingStart >= str.length() - 2 && str.substring(paddingStart).matches("^=+$");
}
private static boolean isValidUnpaddedBase64(final String str) {
// check unpadded Base64 (like Argon2 uses)
// unpadded length should make sense - when padded it should be divisible by 4
int paddedLength = ((str.length() + 3) / 4) * 4;
if (paddedLength - str.length() > 2) {
return false;
}
return str.matches("^[A-Za-z0-9+/]+$");
}
}