Corrige les périodes manquantes de mon adresse IPv4


37

Parfois, lorsque je tape une adresse IPv4, tous les chiffres sont corrects, mais j'oublie de taper un ou plusieurs points. J'aimerais avoir un programme (ou une fonction) qui prend mon adresse IPv4 erronée et génère tous les emplacements valides possibles des périodes manquantes.

Contribution

L'entrée sera toujours une chaîne qui transformera une adresse IPv4 valide (voir les détails ci-dessous). Il aura toujours été transformé uniquement par l'élimination d'un ou plusieurs caractères d'époque.

Votre soumission n'a pas besoin de gérer des entrées en dehors de ce format.

Sortie

Une collection ou une liste, sans ordre ni format particulier, de chaînes représentant toutes les adresses IPv4 valides pouvant être créées à partir de l'entrée en insérant des caractères de période dans l'entrée.

  • La sortie peut être une liste native de la langue ou un autre type de collection ordonné ou non.
  • Alternativement, il peut s'agir d'une séquence de chaîne d'adresse IPv4 délimitée de manière claire.
    • Si vous utilisez un délimiteur à un seul caractère pour délimiter votre chaîne, les points et les chiffres ne sont pas autorisés comme délimiteur à un seul caractère. Je me rends compte que, contrairement aux nombres, les points comme délimiteurs ne sont pas ambigus (car une période sur quatre serait nécessairement un délimiteur), mais par souci de lisibilité, je le refuse.

Format d'adresse IPv4

Bien que les adresses IPv4 ne soient en réalité qu'une séquence de quatre octets binaires, ce défi utilise un format décimal en pointillés restreint.

  • Une adresse IPv4 est composée de quatre valeurs décimales séparées par trois points.
  • Chacune des quatre valeurs sont dans la plage 0à 255inclusivement.
  • Les zéros non significatifs ne sont autorisés dans aucune valeur numérique. (Autonome un caractère 0est permis, tout autre numéro commençant par un zéro n'est pas: 052, 00, etc.)

Cas de test

L'entrée est sur la première ligne, la sortie sur la deuxième ligne (ici, structurée comme une liste de chaînes de caractères citées, séparées par des virgules, séparées par des virgules, entourées de [ ], mais vous pouvez utiliser n'importe quel format ou structure raisonnable, comme spécifié ci-dessus). Certains exemples comportent des notes sur une troisième ligne pour mettre en évidence l'application d'une règle particulière.

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"]

(J'ai fait ces exemples à la main, alors s'il vous plaît, alertez-moi de toute erreur que vous pourriez trouver.)


L'ordre de sortie est-il important?
VOUS

@YOU No: " Une collection ou une liste, sans ordre ni format particulier ... "
apsillers

Les zéros en tête ne sont pas autorisés : cela s'applique-t-il également à l'entrée?
Luis Mendo

3
Donc .... "000125" ne devrait renvoyer qu'une seule solution correcte ... 0.0.0.125?
Keeta

2
@ Keeta C'est tout à fait correct. (Je viens de l'ajouter à titre de test.)
apsillers

Réponses:


9

Pyth, 24 octets

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

Essayez-le en ligne

Comment ça marche

                      ./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 octets, très lent

@FjLL\.,^U256 4./

Attention. Ne cours pas. Nécessite environ 553 Go de RAM.

Comment ça marche

       ,             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

Agréable! Juste pour ma propre compréhension, «toutes les partitions d’entrée» signifie toutes les manières possibles de segmenter l’entrée, non? Donc, vous faites tous les fractionnements possibles, puis vous les rejoignez avec des points, de sorte que vous vous retrouviez avec une foule de candidats comme 1.9.2.1.6.8.1.2et 19.2.1.6.8.1.2etc.? (Mais alors, évidemment, tous les invalides sont filtrés)
apsillers

@apsillers Correct.
Anders Kaseorg

16

C (gcc / linux), 125 121 octets

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

Parcourt toutes les adresses IPv4 possibles et effectue une comparaison personnalisée qui ignore des points supplémentaires dans l'adresse IP générée (mais pas dans l'adresse de comparaison principale) pour décider d'imprimer ou non. Très lent, mais devrait finir en moins d’une heure sur un PC raisonnable .


Vous pouvez enlever le i=0;.
mardi

@ReleasingHeliumNuclei Je pensais que je ne pouvais pas (une fonction doit être réutilisable), mais maintenant je me rends compte qu'après la fonction iest à nouveau 0 ...
orlp

6

Perl 5, 91 octets

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

Le programme attend une seule ligne d'une seule entrée et génère une liste de candidats délimitée par des espaces.

Explication

Le programme exploite la fonction de retour arrière de regex pour couvrir toutes les possibilités de former une adresse IPv4 valide à partir de la chaîne d'entrée.

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

La regex IPv4 avec optionnel ., rien d’important ici.

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

Expression d'évaluation de code qui imprime le contenu des groupes de capture.

^

Faire le match échoue et force le retour en arrière.

Exemple d'exécution

$ 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 octets

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

Edit: sauvegardé 6 octets grâce à @apsillers. A enregistré 6 autres octets en copiant le test de validité de @ YOU.


y at-il une différence entre [1-9] | 0 et [0-9] ou \ d ??
VOUS

@apsillers Ah oui, une version antérieure de mon code pourrait générer une traînée .qui jetterait le test, mais je pense que cette version est OK.
Neil

@YOU Le bit important est que le 0a un $. (Il manque aussi un ^, alors merci d'avoir attiré mon attention dessus.)
Neil

@apsillers Malheureusement, splicecela ne fonctionne pas comme ça, cela modifie le tableau et renvoie tous les éléments supprimés.
Neil

4

Python 3, 232 octets

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

Assez simple: nous plaçons des périodes partout et imprimons si l'adresse IP avec les périodes placées est valide. Nous vérifions la validité des adresses IP en utilisant (ab)ipaddress.ip_address , ce qui déclenche une exception si l'entrée n'est pas une adresse IP valide. Le défi définit certaines règles supplémentaires ip_addressnon gérées (à savoir qu'il ne peut y avoir de zéros non significatifs). Nous vérifions donc celles-ci également avec une expression régulière, puis imprimons.

Affiche chaque solution sur une nouvelle ligne, mélangée avec un nombre arbitraire de lignes vides.

Exemple d'exécution:

$ 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








_

Voici mon ancienne solution Python 2 de 248 octets. Les deuxième et troisième niveaux de retrait sont \t(onglet brut) et \t (onglet brut plus espace) respectivement. Cela joue vraiment mal avec Markdown, donc les onglets ont été remplacés par deux espaces.

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

Nécessite une entrée entourée de guillemets (par exemple "123.456.789"). Affiche chaque adresse IP générée sur une nouvelle ligne.

Sauvegardé 9 octets grâce à @grawity!


1
Serait ipaddress.ip_address()plus court que aton + vérification manuelle?
Grawity


2

Python 3, 262 260 octets

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)])

Aucune bibliothèque utilisée, mais plus tard et plus tard, il se peut que je manque certaines techniques évidentes de golf.

Des résultats quand même.

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
Je pensais que je copierais votre test de validité et je me demandais si vous aviez besoin de parenthèses autour de la orclause?
Neil

@ Neil, merci, je n'avais pas besoin de ça.
VOUS
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.