简体   繁体   English

java.util.UUID.fromString没有检查长度

[英]java.util.UUID.fromString not checking length

When I looked into the implementation of java.util.UUID.fromString , I found that it doesn't check for the UUID length. 当我查看java.util.UUID.fromString的实现时,我发现它没有检查UUID长度。 Is there any particular reason for this? 这有什么特别的原因吗? It only checks the components separated by "-". 它仅检查由“ - ”分隔的组件。

String[] components = name.split("-");
        if (components.length != 5)
            throw new IllegalArgumentException("Invalid UUID string: "+name);

Should it also throw IllegalArgumentException when length is not 36? 当长度不是36时,它是否也会抛出IllegalArgumentException?

Currently, without the length checking, numbers are automatically prepended with 0's if less than the component length or shifted if more. 目前,如果没有长度检查,如果小于组件长度,则数字会自动前置为0,如果更多,则会自动移位。 The downside is, if one entered a UUID string with a missing digit, it is accepted as valid and prepended with 0. This is hard to debug. 缺点是,如果输入一个缺少数字的UUID字符串,它将被接受为有效并且前缀为0.这很难调试。

For example, this "12345678-1234-1234-1234-123456789ab" becomes "12345678-1234-1234-1234-0123456789ab". 例如,“12345678-1234-1234-1234-123456789ab”变为“12345678-1234-1234-1234-0123456789ab”。 Notice the '0' added? 注意添加了'0'? And this "12345678-1234-1234-1234-123456789abcd" becomes "12345678-1234-1234-1234-23456789abcd" with the '1' removed. 并且“12345678-1234-1234-1234-123456789abcd”变为“12345678-1234-1234-1234-23456789abcd”并删除了“1”。

To push this even further, the string "1-2-3-4-5" will also be treated as valid and becomes "00000001-0002-0003-0004-000000000005". 为了进一步推动这一点,字符串“1-2-3-4-5”也将被视为有效并变为“00000001-0002-0003-0004-000000000005”。

Edit: To clarify my question, is this a bug or done on purpose to follow some standard or principle? 编辑:为了澄清我的问题,这是一个错误或有意遵循某些标准或原则吗?

Only the original authors of the UUID class could tell you why they chose not to check the component lengths in the fromString method, but I suspect they were trying to heed Postel's law : 只有UUID类的原作者可以告诉你为什么他们选择不检查fromString方法中的组件长度,但我怀疑他们是在试图注意Postel定律

Be liberal in what you accept, and conservative in what you send. 你所接受的是自由的,你所发送的是保守的。

You can always check the input against a regular expression like this one: 您始终可以针对正则表达式检查输入,如下所示:

[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}

The behaviour of UUID.fromString is strange I am not sure if it is a bug or not, but here is what I have been doing to catch those errors. UUID.fromString的行为很奇怪我不确定它是否是一个bug,但这是我一直在做的,以捕获这些错误。

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;
        }
    }
}

Here's a solution: 这是一个解决方案:

import java.util.UUID
import scala.util.control.Exception._

val uuId: Option[UUID] = allCatch opt UUID.fromString(uuidToTest)
require(uuId.isDefined, "invalid UUID")

Make sure to test against id.equalsIgnoreCase(parsed.toString()) because UUID.fromString(id) returns lower case even if you pass id as upper case. 确保对id.equalsIgnoreCase(parsed.toString())进行测试,因为即使将id作为大写传递, UUID.fromString(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;
        }
    }
}

A copy of ams's answer but for scala xD ams答案的副本,但是对于scala xD

def isValidUuid(uuid: String): Boolean =
    try uuid != null && UUID.fromString(uuid).toString.equals(uuid)
    catch {
      case e: IllegalArgumentException => false
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM