修正我的IPv4地址的缺失期


37

有时,当我输入一个IPv4地址时,我会正确地输入所有数字,但忘记输入一个或多个句点。我想要一个程序(或函数),该程序可以使用损坏的IPv4地址并输出缺失期的所有可能有效位置。

输入值

输入将始终是一个字符串,该字符串是有效IPv4地址的转换(请参见下面的详细信息)。它总是将仅通过消除一个或多个时期字符来进行转换。

您的提交不需要处理此格式以外的输入。

输出量

代表所有有效IPv4地址的字符串的集合或列表(没有特定的顺序或格式),可以通过在输入中插入句点字符来从输入中创建所有有效的IPv4地址。

  • 输出可以是语言本机列表或其他有序或无序集合类型。
  • 替代地,它可以是以某种明确方式界定的IPv4地址的字符串序列。
    • 如果您使用单字符定界符来分隔字符串,则不允许使用句点和数字作为该单字符定界符。我认识到,与数字不同,句点作为分隔符不是模棱两可的(因为每个第四个句点都必须是分隔符),但是出于可读性考虑,我不允许这样做。

IPv4地址格式

尽管IPv4地址实际上只是四个二进制八位字节的序列,但此挑战使用了受限的点分十进制格式。

  • IPv4地址是由三个句点分隔的四个十进制值。
  • 每四个值的范围是0255,包容性。
  • 任何数字值都不允许前导零。(独立单字符0被允许;开始与零的任何其它数量不是:05200等)

测试用例

输入在第一行上,输出在第二行上(此处,结构是用逗号分隔的带引号的字符串列表,用逗号分隔,并用包围[ ],但是您可以使用上面指定的任何合理的格式或结构)。一些示例在第三行上有注释,以突出显示特定规则的应用。

192.168.1234
["192.168.1.234", "192.168.12.34", "192.168.123.4"]

192.1681234
["192.16.81.234", "192.168.1.234", "192.168.12.34", "192.168.123.4"]
(Note: 192.1681.2.34 (etc.) is illegal because 1681 is greater than 255)

1921681.234
["19.216.81.234", "192.16.81.234", "192.168.1.234"]

1921681234
["19.216.81.234", "192.16.81.234", "192.168.1.234", "192.168.12.34", "192.168.123.4"]

192.168.1204
["192.168.1.204", "192.168.120.4"]
(Note: 192.168.12.04 is illegal because of leading zero)

192.168.123
["1.92.168.123", "19.2.168.123", "192.1.68.123", "192.16.8.123", "192.168.1.23", "192.168.12.3"]

192.168.256
["192.168.2.56", "192.168.25.6"]
(Note: Any combination that would leave 256 intact is illegal)

120345
["1.20.3.45", "1.20.34.5", "1.203.4.5", "12.0.3.45", "12.0.34.5", "120.3.4.5"]
(Note: 12.03.4.5 (etc.) is illegal due to leading zero.)

012345
["0.1.23.45", "0.1.234.5", "0.12.3.45", "0.12.34.5", "0.123.4.5"]
(Note: the first segment must be 0, because `01` or `012` would be illegal.)

000123
["0.0.0.123"]

(我手工制作了这些示例,因此,如果您发现任何错误,请提醒我。)


输出顺序有关系吗?

@YOU否:“ 集合或列表,无特定顺序或格式...
apsillers'Aug

不允许前导零:这也适用于输入吗?
路易斯·门多

3
所以...“ 000125”应该只返回一种正确的解决方案... 0.0.0.125?
Keeta

2
@Keeta完全正确。(我只是将其添加为测试用例。)
apsillers'Aug

Answers:


9

Pyth,24个字节

f&q4lJcT\.!-J`M256jL\../

在线尝试

这个怎么运作

                      ./Q   all partitions of input
                  jL\.      join each on .
f                           filter for results T such that:
      cT\.                    split T on .
     J                        assign to J
    l                         length
  q4                          equals 4
 &                            … and:
           -J`M256              J minus the list of representations of [0, …, 255]
          !                     is false (empty)

Pyth,17个字节,非常慢

@FjLL\.,^U256 4./

警告。别跑。 需要大约553 GiB的RAM。

这个怎么运作

       ,             two-element list of:
        ^U256 4        all four-element lists of [0, …, 255]
               ./Q     all partitions of input
  jLL\.              join each element of both on .
@F                   fold intersection

真好!仅以我自己的理解,“输入的所有分区”意味着分割输入的所有可能方式,对吗?所以,你尽一切可能的分割,然后归队与时间的裂缝,所以你最终喜欢的候选人的负荷1.9.2.1.6.8.1.219.2.1.6.8.1.2等?(但是显然所有无效的都被过滤掉了)
apsillers'Aug

@apsillers正确。
安德斯·卡塞格

16

C(gcc / linux),125 121字节

i;f(char*a){do{char*y=a,s[99],*x=inet_ntop(2,&i,s,99);for(;*x&&!(*x^*y&&*x^46);++x)y+=*x==*y;*x|*y||puts(s);}while(++i);}

循环遍历所有可能的IPv4地址,并进行自定义比较,以跳过生成的ip地址(而不是主比较地址)中的多余点,以决定是否打印。速度很慢,但是应该在一台合理的PC上在1小时内完成


您可以删除i=0;
betseg

@ReleasingHeliumNuclei我以为我做不到(一个函数必须可重用),但是现在我意识到,在该函数i再次为0以后……
orlp

6

Perl 5,91个字节

<>=~/^(([1-9]?|1\d|2[0-4])\d|25[0-5])\.?((?1))\.?((?1))\.?((?1))$(?{print"$1.$3.$4.$5 "})^/

该程序期望单个输入的一行,并输出以空格分隔的候选列表。

说明

该程序利用regex的回溯功能来循环所有从输入字符串中形成有效IPv4地址的可能性。

^(([1-9]?|1\d|2[0-4])\d|25[0-5])\.?((?1))\.?((?1))\.?((?1))$

具有可选功能的IPv4正则表达式,.此处无须注意。

(?{print"$1.$3.$4.$5 "})

代码评估表达式打印出捕获组的内容。

^

使比赛失败并强制回溯。

运行示例

$ echo "012345" | perl G89503.pl
0.12.34.5 0.12.3.45 0.1.23.45 0.1.234.5 0.123.4.5

5

的JavaScript(ES6),147个 141 135字节

f=(s,n=0)=>(a=s.split`.`)[3]?a.every(s=>s==`0`|s[0]>0&s<256)?s+' ':'':[...s].map((_,i)=>i>n?f(s.slice(0,i)+`.`+s.slice(i),i):``).join``
<input placeholder=Input oninput=o.textContent=f(this.value)><div id=o style=font-family:monospace;width:1em>Output

编辑:由于@apsillers,节省了6个字节。通过复制@YOU的有效性测试,又节省了6个字节。


[1-9] | 0和[0-9]或\ d之间有区别吗?

@apsillers嗯,是的,我的代码的早期版本可能会生成尾随.,从而引发测试,但是我认为此版本可以。
尼尔

@YOU最重要的一点是,0有一个$。(它也缺少a ^,所以感谢您引起我的注意。)
Neil

@apsillers可悲的是,splice它不能那样工作,它会修改数组并返回所有已删除的元素。
尼尔

4

Python 3,232字节

import re,itertools as t,ipaddress as k
R=range
i=input()
for d in R(5):
 for p in t.combinations(R(len(i)),d):
  n=i;o=0
  for a in p:n=n[:a+o]+'.'+n[a+o:];o+=1
  try:k.ip_address(n);print(n*(not re.search(r'\D?0\d',n)))
  except:0

非常简单:我们将句点放在所有位置,并在放置了句点的IP地址有效时进行打印。我们通过(ab)using检查IP地址的有效性,ipaddress.ip_address如果输入的IP地址无效,则会引发异常。挑战定义了一些其他ip_address无法处理的规则(即,不能有前导零),因此我们也使用正则表达式检查这些规则,然后打印。

在新行上输出每个解决方案,并与任意数量的空白行混合。

示例运行:

$ echo 012345 | python fixip.py
0.1.23.45
0.1.234.5
0.12.3.45
0.12.34.5
0.123.4.5





$ echo 000123 | python fixip.py
0.0.0.123








_

这是我较旧的248字节Python 2解决方案。第二和第三缩进级别分别是\t(原始选项卡)和\t (原始选项卡加空格)。这对Markdown 真的很不利,因此选项卡已被替换为两个空格。

import socket,re,itertools as t
R=range
i=input()
for d in R(5):
 for p in t.combinations(R(len(i)),d):
  n=i;o=0
  for a in p:n=n[:a+o]+'.'+n[a+o:];o+=1
  try:
   socket.inet_aton(n)
   if n.count('.')==3and not re.search(r'\D?0\d',n):print n
  except:0

需要输入用引号引起来(例如"123.456.789")。在新行上输出每个生成的IP地址。

@grawity节省了9个字节!


1
ipaddress.ip_address()比aton + manual check短吗?
grawity


2

Python 3中,262 260个字节

p,l,L,T=set(),-1,len,tuple
while l<L(p):l=L(p);p|={T(z[:i]+(y[:j],y[j:])+z[i+1:])for z in set(p)or[T(input().split("."))]for i,y in enumerate(z)for j in range(1,L(y))}
print(['.'.join(x)for x in p if L(x)==4and all(y=='0'or y[0]!='0'and int(y)<256for y in x)])

没有使用任何库,但是时间更长或更久,可能是我缺少一些明显的高尔夫技术。

反正结果。

for x in 192.168.1234 192.1681234 1921681.234 1921681234 192.168.1204 192.168.123 192.168.256 120345 012345 000123; do
echo $x | python3 ipv4.py
done;

['192.168.123.4', '192.168.1.234', '192.168.12.34']
['192.16.81.234', '192.168.1.234', '192.168.123.4', '192.168.12.34']
['19.216.81.234', '192.168.1.234', '192.16.81.234']
['19.216.81.234', '192.168.123.4', '192.168.12.34', '192.16.81.234', '192.168.1.234']
['192.168.1.204', '192.168.120.4']
['192.16.8.123', '19.2.168.123', '1.92.168.123', '192.168.1.23', '192.168.12.3', '192.1.68.123']
['192.168.25.6', '192.168.2.56']
['1.20.3.45', '1.203.4.5', '12.0.34.5', '120.3.4.5', '1.20.34.5', '12.0.3.45']
['0.1.23.45', '0.12.3.45', '0.12.34.5', '0.123.4.5', '0.1.234.5']
['0.0.0.123']

1
我以为我会复制您的有效性测试,并且想知道是否需要该or子句的括号?
尼尔

@Neil,谢谢,不需要那些。
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.