java IPv6 验证
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5963199/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
IPv6 validation
提问by Tony
I used IPAddressUtil.isIPv6LiteralAddress (ipAddress)
method to validate IPv6, but this method fails for ipv6-address/prefix-length format (format is mentioned in RFC 4291section 2.3) of IPV6.
我使用IPAddressUtil.isIPv6LiteralAddress (ipAddress)
了验证 IPv6 的方法,但是对于 IPv6 的 ipv6-address/prefix-length 格式(格式在RFC 4291第 2.3 节中提到),此方法失败。
Could anyone know any validators which validate " ipv6-address/prefix-length " format?
谁能知道任何验证“ipv6-address/prefix-length”格式的验证器?
Legal representations of IPV6
IPV6的法律代表
- ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
- 2001:DB8:0:0:8:800:200C:417A
- FF01:0:0:0:0:0:0:101
- 0:0:0:0:0:0:0:1
- 0:0:0:0:0:0:0:0
- 2001:DB8::8:800:200C:417A
- FF01::101
- ::1
- ::
- 0:0:0:0:0:0:13.1.68.3
- 0:0:0:0:0:FFFF:129.144.52.38
- ::13.1.68.3
- FFFF:129.144.52.38
- 2001:0DB8:0000:CD30:0000:0000:0000:0000/60
- 2001:0DB8::CD30:0:0:0:0/60
- 2001:0DB8:0:CD30::/60
- ABCD:EF01:2345:6789:ABCD:EF01:2345:6789
- 2001:DB8:0:0:8:800:200C:417A
- FF01:0:0:0:0:0:0:101
- 0:0:0:0:0:0:0:1
- 0:0:0:0:0:0:0:0
- 2001:DB8::8:800:200C:417A
- FF01::101
- ::1
- ::
- 0:0:0:0:0:0:13.1.68.3
- 0:0:0:0:0:FFFF:129.144.52.38
- ::13.1.68.3
- FFFF:129.144.52.38
- 2001:0DB8:0000:CD30:0000:0000:0000:0000/60
- 2001:0DB8::CD30:0:0:0:0/60
- 2001:0DB8:0:CD30::/60
NOT legal representations of IPV6
非 IPV6 的法律代表
- 2001:0DB8:0:CD3/60
- 2001:0DB8::CD30/60
- 2001:0DB8::CD3/60
- 2001:0DB8:0:CD3/60
- 2001:0DB8::CD30/60
- 2001:0DB8::CD3/60
采纳答案by Security Hound
See if this works:
看看这是否有效:
try {
if (subjectString.matches(
"(?ix)\A(?: # Anchor address\n" +
" (?: # Mixed\n" +
" (?:[A-F0-9]{1,4}:){6} # Non-compressed\n" +
" |(?=(?:[A-F0-9]{0,4}:){2,6} # Compressed with 2 to 6 colons\n" +
" (?:[0-9]{1,3}\.){3}[0-9]{1,3} # and 4 bytes\n" +
" \z) # and anchored\n" +
" (([0-9A-F]{1,4}:){1,5}|:)((:[0-9A-F]{1,4}){1,5}:|:) # and at most 1 double colon\n" +
" |::(?:[A-F0-9]{1,4}:){5} # Compressed with 7 colons and 5 numbers\n" +
" )\n" +
" (?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.){3} # 255.255.255.\n" +
" (?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9]) # 255\n" +
"| # Standard\n" +
" (?:[A-F0-9]{1,4}:){7}[A-F0-9]{1,4} # Standard\n" +
"| # Compressed\n" +
" (?=(?:[A-F0-9]{0,4}:){0,7}[A-F0-9]{0,4} # Compressed with at most 7 colons\n" +
" \z) # and anchored\n" +
" (([0-9A-F]{1,4}:){1,7}|:)((:[0-9A-F]{1,4}){1,7}|:) # and at most 1 double colon\n" +
"|(?:[A-F0-9]{1,4}:){7}:|:(:[A-F0-9]{1,4}){7} # Compressed with 8 colons\n" +
")/[A-F0-9]{0,4}\z # Anchor address"))
{
// String matched entirely
} else {
// Match attempt failed
}
} catch (PatternSyntaxException ex) {
// Syntax error in the regular expression
}
I purchased a very helpful program called RegexMagic nearly a year ago for some complicated regular expressions I planned on using.
大约一年前,我为一些我计划使用的复杂正则表达式购买了一个非常有用的程序,称为 RegexMagic。
This was suppose to be Java, so it should compile, I assume the /60 can be between the ranges of 0000 and FFFF you can modify that last part.
这假设是 Java,所以它应该编译,我假设 /60 可以在 0000 和 FFFF 的范围之间,你可以修改最后一部分。
/[A-F0-9]{0,4} is what I added to the regular expression to match your example.
/[A-F0-9]{0,4} 是我添加到正则表达式中以匹配您的示例的内容。
回答by broc.seib
You can use the Guava library, specifically using the com.google.common.net.InetAddresses
class, calling isInetAddress()
.
您可以使用 Guava 库,特别是使用com.google.common.net.InetAddresses
类,调用isInetAddress()
.
isInetAddress
isInet地址
public static boolean isInetAddress(String ipString)
public static boolean isInetAddress(String ipString)
Returns true if the supplied string is a valid IP string literal, false otherwise.
如果提供的字符串是有效的 IP 字符串文字,则返回 true,否则返回 false。
Parameters: ipString
- String to evaluated as an IP string literal
参数:ipString
- 被评估为 IP 字符串文字的字符串
Returns: true
if the argument is a valid IP string literal
返回:true
如果参数是有效的 IP 字符串文字
回答by Sean F
The IPAddress Java librarysupports parsing both IPv4 and IPv6 CIDR subnets (ie address/prefix format) in a polymorphic manner. Disclaimer: I am the project manager.
IPAddress Java 库支持以多态方式解析 IPv4 和 IPv6 CIDR 子网(即地址/前缀格式)。免责声明:我是项目经理。
The following method is example code for validating:
以下方法是用于验证的示例代码:
static void parse(String str) {
IPAddressString addrString = new IPAddressString(str);
try {
IPAddress addr = addrString.toAddress();
IPAddress hostAddr = addrString.toHostAddress();
Integer prefix = addr.getNetworkPrefixLength();
if(prefix == null) {
System.out.println(addr + " has no prefix length");
} else {
System.out.println(addr + " has host address " + hostAddr + " and prefix length " + prefix);
}
} catch(AddressStringException e) {
System.out.println(addrString + " is invalid: " + e.getMessage());
}
}
Using the examples provided in the question, the output of the above method is:
使用问题中提供的示例,上述方法的输出为:
abcd:ef01:2345:6789:abcd:ef01:2345:6789 has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
2001:db8::8:800:200c:417a has no prefix length
ff01::101 has no prefix length
::1 has no prefix length
:: has no prefix length
::d01:4403 has no prefix length
::ffff:8190:3426 has no prefix length
::d01:4403 has no prefix length
FFFF:129.144.52.38 is invalid: FFFF:129.144.52.38 IP Address error: address has too few segments
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:db8:0:cd30::/60 has host address 2001:db8:0:cd30:: and prefix length 60
2001:0DB8:0:CD3/60 is invalid: 2001:0DB8:0:CD3/60 IP Address error: address has too few segments
2001:db8::cd30/60 has host address 2001:db8::cd30 and prefix length 60
2001:db8::cd3/60 has host address 2001:db8::cd3 and prefix length 60
As you can see, the question was incorrect about FFFF:129.144.52.38 being valid and about 2001:db8::cd30/60 and 2001:db8::cd3/60 being invalid. The first one would be valid if it were ::FFFF:129.144.52.38
如您所见,关于 FFFF:129.144.52.38 有效而关于 2001:db8::cd30/60 和 2001:db8::cd3/60 无效的问题是不正确的。如果第一个是有效的 ::FFFF:129.144.52.38
回答by al0
Strictly speaking, a section 2.3 does not describe an address representation, but a representation of address prefix(even the "full-length" prefix is not the same as an address).
严格来说,2.3节没有描述地址表示,而是地址前缀的表示(即使是“全长”前缀也不等同于地址)。
An IPv6 address prefix is represented by the notation: ipv6-address/prefix-length where ipv6-address is an IPv6 address in any of the notations listed in Section 2.2.
IPv6 地址前缀由以下符号表示: ipv6-address/prefix-length 其中 ipv6-address 是第 2.2 节中列出的任何符号中的 IPv6 地址。
That means you may safely disregard this format if you need to validate addresses.
这意味着如果您需要验证地址,您可以安全地忽略此格式。
回答by Honwhy Wang
My idea is to split it into two part, prefix address and prefix len.
我的想法是把它分成两部分,前缀地址和前缀len。
1. validate prefix address use the some regex to validate IPv6 address
2. validate the prefix len that must be an integer
3. prefix address can only have ':' s less than the result ofprefix len divided by 16
4. other logic must be considered as well, leave TODOs here, sorry:(
1. 验证前缀地址 使用一些正则表达式来验证 IPv6 地址
2. 验证前缀 len 必须是整数
3. 前缀地址只能有 ':' 小于prefix len divided by 16
4的结果。
其他逻辑也必须考虑,把待办事项留在这里,对不起:(
private int validateIPv6AddrWithPrefix(String address) {
int occurCount = 0;
for(char c : address) {
if(c=='/'){
occurCount++;
}
}
if(occurCount != 1){
//not good, to much / character
return -1;
}
/* 2nd element should be an integer */
String[] ss = pool.getAddress().split("/");
Integer prefixLen = null;
try{
prefixLen = Integer.valueOf(ss[1]);
// TODO validate the prefix range(1, 128)
}catch(NumberFormatException e) {
/* not a Integer */
return -1;
}
/* 1st element should be ipv6 address */
if(!IPaddrUtilities.isIPv6Address(ss[0])) {
return -1;
}
/* validate ':' character logic */
occurCount = 0;
for(char c : ss[0].toCharArray()){
if(c==':') {
occurCount++;
}
}
if(occurCount >= prefixLen/16) {
// to much ':' character
return -1;
}
return 0;
}
回答by Bhargav Modi
I had tried below regex in java and it worked for IPV4 and IPV6
我曾在 java 中尝试过下面的正则表达式,它适用于 IPV4 和 IPV6
public class Utilities {
private static Pattern VALID_IPV4_PATTERN = null;
private static Pattern VALID_IPV6_PATTERN = null;
private static final String ipv4Pattern = "(([01]?\d\d?|2[0-4]\d|25[0-5])\.){3}([01]?\d\d?|2[0-4]\d|25[0-5])";
private static final String ipv6Pattern = "([0-9a-f]{1,4}:){7}([0-9a-f]){1,4}";
static {
try {
VALID_IPV4_PATTERN = Pattern.compile(ipv4Pattern, Pattern.CASE_INSENSITIVE);
VALID_IPV6_PATTERN = Pattern.compile(ipv6Pattern, Pattern.CASE_INSENSITIVE);
} catch (PatternSyntaxException e) {
//logger.severe("Unable to compile pattern", e);
}
}
/**
* Determine if the given string is a valid IPv4 or IPv6 address. This method
* uses pattern matching to see if the given string could be a valid IP address.
*
* @param ipAddress A string that is to be examined to verify whether or not
* it could be a valid IP address.
* @return <code>true</code> if the string is a value that is a valid IP address,
* <code>false</code> otherwise.
*/
public static boolean isIpAddress(String ipAddress) {
Matcher m1 = Utilities.VALID_IPV4_PATTERN.matcher(ipAddress);
if (m1.matches()) {
return true;
}
Matcher m2 = Utilities.VALID_IPV6_PATTERN.matcher(ipAddress);
return m2.matches();
}
}