Java.util.UUID.fromString не проверяет длину
Когда я посмотрел на реализацию java.util.UUID.fromString
, я обнаружил, что он не проверяет длину UUID. Есть ли какая-то особая причина для этого? Он проверяет только компоненты, разделенные символом "-".
String[] components = name.split("-");
if (components.length != 5)
throw new IllegalArgumentException("Invalid UUID string: "+name);
Должен ли он также вызывать исключение IllegalArgumentException, если длина не равна 36?
В настоящее время без проверки длины числа автоматически добавляются с 0, если меньше, чем длина компонента или сдвинуты, если больше. Недостатком является то, что если вы ввели строку UUID с отсутствующей цифрой, она принимается как действительная и добавляется с 0. Это трудно отлаживать.
Например, этот "12345678-1234-1234-1234-123456789ab" становится "12345678-1234-1234-1234-0123456789ab". Обратите внимание, что добавлено '0'? И этот "12345678-1234-1234-1234-123456789abcd" становится "12345678-1234-1234-1234-23456789abcd" с удаленным "1".
Чтобы сделать это еще дальше, строка "1-2-3-4-5" также будет считаться действительной и станет "00000001-0002-0003-0004-000000000005".
Изменить: Чтобы уточнить мой вопрос, является ли это ошибкой или сделано для того, чтобы следовать стандарту или принципу?
Ответы
Ответ 1
Только оригинальные авторы UUID-класса могут рассказать вам, почему они решили не проверять длины компонентов в методе fromString, но я подозреваю, что они пытались прислушаться Закон о Postel:
Будьте либеральны в том, что вы принимаете, и консервативны в том, что вы отправляете.
Вы всегда можете проверить ввод на регулярное выражение, подобное этому:
[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}
Ответ 2
Поведение UUID.fromString странно, я не уверен, что это ошибка или нет, но вот что я делаю, чтобы поймать эти ошибки.
public class UUIDUtils {
public static boolean isValid(String uuid){
if( uuid == null) return false;
try {
// we have to convert to object and back to string because the built in fromString does not have
// good validation logic.
UUID fromStringUUID = UUID.fromString(uuid);
String toStringUUID = fromStringUUID.toString();
return toStringUUID.equals(uuid);
} catch(IllegalArgumentException e) {
return false;
}
}
}
Ответ 3
Здесь решение:
import java.util.UUID
import scala.util.control.Exception._
val uuId: Option[UUID] = allCatch opt UUID.fromString(uuidToTest)
require(uuId.isDefined, "invalid UUID")
Ответ 4
Обязательно проверьте id.equalsIgnoreCase(parsed.toString())
, потому что UUID.fromString(id)
возвращает строчный регистр, даже если вы передаете id
в качестве верхнего регистра.
@Component
public class UuidDtoValidator {
public boolean isValidUuid(String id) {
if (isBlank(id)) {
return false;
}
try {
UUID parsed = UUID.fromString(id);
if (parsed.equals(new UUID(0, 0))) {
return false;
}
return id.equalsIgnoreCase(parsed.toString());
} catch (IllegalArgumentException e) {
return false;
}
}
}
Ответ 5
Копия ответа ams, но для scala xD
def isValidUuid(uuid: String): Boolean =
try uuid != null && UUID.fromString(uuid).toString.equals(uuid)
catch {
case e: IllegalArgumentException => false
}