IPアドレスかどうか?


25

ネットワークスキャンツールは、入力についてうるさくうるさいので、不適切な文字を含むIPv4アドレスまたは適切にフォーマットされていないIPv4アドレスを入力すると、すぐにクラッシュします。

IPv4アドレスは、ピリオドで区切られた4つの数字として記述された32ビットの数値アドレスです。各番号は0〜255にできます。

これらのクラッシュを回避するために、入力を事前検証するツールを作成する必要がありますが、特定のツールには注意が必要です。有効な形式はa.b.c.d、a、b、c、dのようになります。

  • 先行ゼロなしの0自然数または自然数を指定できます。
  • 0から255の間(両端を含む)でなければなりません。
  • 必要がありませんのような特殊な記号含まれ+-,、などを。
  • 10進数でなければなりません(基数10

入力:文字列

出力:TruthyまたはFalseyの値(任意の値も受け入れられます)

テストケース

Input            |  Output  |  Reason
                 |          |
- 1.160.10.240   |  true    |
- 192.001.32.47  |  false   |  (leading zeros present)
- 1.2.3.         |  false   |  (only three digits)
- 1.2.3          |  false   |  (only three digits)
- 0.00.10.255    |  false   |  (leading zeros present)
- 1.2.$.4        |  false   |  (only three digits and a special symbol present)
- 255.160.0.34   |  true    |
- .1.1.1         |  false   |  (only three digits)
- 1..1.1.1       |  false   |  (more than three periods)
- 1.1.1.-0       |  false   |  (special symbol present)
- .1.1.+1        |  false   |  (special symbol present)
- 1 1 1 1        |  false   |  (no periods)
- 1              |  false   |  (only one digit)
- 10.300.4.0     |  false   |  (value over 255)
- 10.4F.10.99    |  false   |  (invalid characters)
- fruit loops    |  false   |  (umm...)
- 1.2.3.4.5      |  false   |  (too many periods/numbers)
- 0.0.0.0        |  true    |
- 0.0 0.0.       |  false   |  (periods misplaced)
- 1.23..4        |  false   |  (a typo of 1.2.3.4)
- 1:1:1:1:1:1:1:1|  false   |  (an IPv6 address, not IPv4)

これはなので、最少バイトが勝ちます!

ユーザーへの注意 -テストケースをさらに追加する場合は、(編集を提案することで)歓迎されます。しかし、テストケースが繰り返されないようにしてください!ありがとう


10
テストケースを提案します:1.1.1.1.11.1.1.1..1.1.11..1.11..1.1.11.1.1.01.1.1.-01.1.1.+11.1.1.1E11.1.1.2561.1.1.0x1255.255.255.2550.0.0.0'or 1=1--<empty string>1 1 1 11,1,1,1
tsh

5
テストケース「1.2.3.4.5」(長すぎるIPを除外する)および「999.0.0.0」(大きすぎるIPを除外する)を追加することを提案します。
トリガー測定

5
おそらく少しうるさいですが、おそらく「IPアドレス」ではなく「IPv4アドレス」を参照する必要があります-または、少なくともIPv4アドレスを意味することをどこかに言及する必要があります-それ以外の場合は1234:5678 :: 1は有効なIPアドレスである必要があります説明から、それが意図されていないことは明らかです:)
psmears

3
@Criggie前提は、実際にすべての実際の IP4ルール(あなたが言及したような)を実際にチェックすることではなく、入力文字列が非常に特定の形式での入力のみを許可する他の(おそらく不適切に書かれた)アプリをクラッシュさせないことを保証することです。また、既に30以上の回答があるチャレンジのルールは変更しません。
BradC

2
@Criggie Worthは、RFCが「アドレスは4オクテットの固定長」であると宣言していることに注目しています。あなたが参照しているフリンジケースは、この課題よりも専門的だと思います。
ポケ

回答:


26

X86_64マシンコード: 18 16バイト

編集:この答えはまったく機能しません。

  1. 私はinet_pton標準のCライブラリから使用しています。つまり、externが必要です。ただし、バイトカウントにはexternを含めませんでした。
  2. 実際の住所の結果としてレッドゾーンを使用しましたが、レッドゾーンを使用することもできた関数を呼び出しました。幸いなことに私のマシンでは動作しませんが、奇妙な標準ライブラリビルドがそれを使用し、未定義の動作を引き起こす可能性があります。

そして、ええ、すべてはすでに書かれた関数によってほとんど行われています

とにかく、これは私が得たものです: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

アセンブリ:

section .text
    extern inet_pton
    global ipIsValid

ipIsValid:
    mov rsi, rdi
    ;mov rdi, 2 ; change to 10 for ipv6
    push 2
    pop rdi ; thank you peter
    lea rdx, [rsp - 128]
    jmp inet_pton

説明:

を見てくださいinet_pton(3)。文字列IPアドレスを取得し、それを使用できるバッファに入れますstruct sockaddr。3つの引数を取ります:アドレスファミリ(AF_INET(ipv4)、2、またはAF_INET6(ipv6)、10)、ipアドレスの文字列、および出力へのポインタ。成功した場合は1、無効なアドレスの場合は0、アドレスファミリがどちらAF_INETでもない場合は-1を返しますAF_INET6(定数を渡すため発生しません)。

したがって、結果を気にしないので、2番目の引数のレジスタに文字列を移動し、最初のレジスタを2に設定し、3番目のレジスタをレッドゾーン(スタックポインタの下128バイト)に設定します。その後、単純jmpinet_pton呼び出し元にそれを返すことができます!

ケースをテストするために、このクイックテストプログラムを作成しました。

#include <stdio.h>
#include <arpa/inet.h>
#include <netinet/ip.h>

extern int ipIsValid(char *);

int main(){
    char *addresses[] = {
        "1.160.10.240",
        "192.001.32.47",
        "1.2.3.",
        "1.2.3",
        "0.00.10.255",
        "1.2.$.4",
        "255.160.0.34",
        ".1.1.1",
        "1..1.1.1",
        "1.1.1.-0",
        ".1.1.+1",
        "1 1 1 1",
        "1",
        "10.300.4.0",
        "10.4F.10.99",
        "fruit loops",
        "1.2.3.4.5",
        NULL
    };

    for(size_t i = 0; addresses[i] != NULL; ++i){
        printf("Address %s:\t%s\n", addresses[i],
            ipIsValid(addresses[i]) ? "true" : "false");
    }
    return 0;
}

でアセンブルしnasm -felf64 assembly.asm、でコンパイルするとgcc -no-pie test.c assembly.o、次のものが得られます。

Address 1.160.10.240:   true
Address 192.001.32.47:  false
Address 1.2.3.: false
Address 1.2.3:  false
Address 0.00.10.255:    false
Address 1.2.$.4:    false
Address 255.160.0.34:   true
Address .1.1.1: false
Address 1..1.1.1:   false
Address 1.1.1.-0:   false
Address .1.1.+1:    false
Address 1 1 1 1:    false
Address 1:  false
Address 10.300.4.0: false
Address 10.4F.10.99:    false
Address fruit loops:    false
Address 1.2.3.4.5:  false

呼び出し元が関数を渡すAF_INETAF_INET6、関数に渡されることになっている場合、これをもっと小さくすることができます


4
あなたがASMでこれをしたことが大好きです。そして、あなたがそれを理解していないかもしれない人にそれを説明したという事実(そしてテストコード)はさらに良いです。それは私がasmでそれをしたかもしれないと言うことではありません; あまりにも長い年月が過ぎましたが、私はあなたの説明(そしてプロセス)が何を言っているのかを正確に見るのに十分なことを覚えています。よくできました。
プリフタン

4
e9 00 00 00 00はa jmp near $+5であり、a ではありませんjmp inet_pton。オペコードを提供する場合はinet_pton、空白のままにせず、
組み込み

1
15バイト-TIO 32ビットのx86
Logern

3
プログラムが必要とするものであり、すべてのプラットフォームで利用できるわけではないため、回答タイトルにexternを含める必要があります。
qwr

1
「mov rdi、2」は、-2バイトの場合「push 2 / pop rdi」にすることができます。また、逆アセンブリまたはコードが間違っていることに注意してください。「mov edi」(rdiではない)か、プレフィックスが欠落しています。
ピーターフェリー

13

Java(JDK)、63バイト

s->("."+s).matches("(\\.(25[0-5]|(2[0-4]|1\\d|[1-9])?\\d)){4}")

オンラインでお試しください!

クレジット


末尾のセミコロンを削除するのを忘れました。;)そして、コメントにあるものを含め、すべてのテストケースで機能することを確認できます。私はゴルフにいくつかのものを見れば見るでしょう。
ケビンクルーイッセン

3
失敗しました.1.2.3.4
l4m2

明示的に0/1が必要な場合、ブール値を使用できますか?
l4m2

1
@ l4m2元の質問には有効/無効がありました。そのため、ここでは真偽値を受け入れられると想定しています。
ケビンクルーイッセン

Output: 0 or 1そして、Javaには、自動bool-> int型持っていない
l4m2

12

JavaScript(Node.js)、43バイト

x=>x.split`.`.map(t=>[t&255]==t&&[])==`,,,`

オンラインでお試しください!

JavaScript(Node.js)、46バイト

x=>x.split`.`.every(t=>k--&&[t&255]==t,k=4)*!k

オンラインでお試しください!

Arnauldのパーツを使用

JavaScript(Node.js)54 53 51バイト

x=>x.split`.`.every(t=>k--*0+t<256&[~~t]==t,k=4)*!k

オンラインでお試しください!

-2B 0+t<256、パトリックステファンセンから-1B、入力を避けるための+ 1B1.1.1.1e-80

RegExpソリューション58 54バイト

s=>/^((2(?!5?[6-9])|1|(?!0\d))\d\d?\.?\b){4}$/.test(s)

Deadcodeに3バイトありがとう


テストケースをいくつか追加しました!
rv7


1
@KevinCruijssen 0.0.0.0はここで本当です。なぜSQLインジェクションがここにあるのでしょうか?
l4m2

待って、チャレンジの説明の文を誤解しています。0.0.0.0本当に真実です。それも私の答えをゴルフします..(そして、SQLインジェクションとはどういう意味ですか?:SリンクはすべてのテストケースのTIOにあります。)
ケビンCruijssen

1
@ l4m2 IPアドレスのように見えないテストケースが必要なため追加しました。
tsh

11

PHP39 36バイト

<?=+!!filter_var($argv[1],275,5**9);

オンラインでお試しください!

275は定数に似ています FILTER_VALIDATE_IP

定数の代わりに5 ** 9が使用されています FILTER_FLAG_IPV4ます。5**9 & FILTER_FLAG_IPV4Benoit Esnardが指摘したように、これはPHPがバックグラウンドで行うこととまったく同じであるため、これは十分です。

ここで、filter_var有効なIPv4アドレスである場合は最初の引数を返し、そうでない場合はfalseを返します。では+!!、チャレンジに必要な出力を生成します。


3
ここで3バイト5**91048576節約する代わりにを使用すると、PHPは&IPv4 / IPv6フラグをテストするために使用するため、 1048576から2097151までの任意の数値が有効です。
ブノワエズナード

私はあなたの答えを(基本的に)私の答えであるためにここに投票します:codegolf.stackexchange.com/a/174470/14732これは2018-10-22 09:17:34UTCに書かれたものであり、あなたのものは2018-10-22 09に書かれました: 21:55UTC。@BenoitEsnardによって与えられた1バイトの最適化を元に戻したとしても、私の答えは機能的にはあなたのものとまったく同じです。
イスマエルミゲル

2
謝罪する必要がありますが、あなたの答えはわかりませんでしたが、作成中にこの質問に関するPHPの提出はありませんでした(あなたが言ったように、時間差は5分未満です)。
oktupol

私は知っていますし、理解しています。ちょうど今あなたに気づいた。私は私のものをロールバックすることができ、あなたは最適化を維持します。しかし、答えがお互いに十分に異なっているかどうかはわかりません。
イスマエルミゲル

17
@IsmaelMiguelあなたが彼らが始まったときにそこにいなかったのがもっともらしいのなら、私はそのために誰かに投票しません。5分の違いはありますが、もっともらしいだけでなく、ほぼ間違いなくそうです。
ダンカンXシンプソン

11

PHP、36バイト

echo(ip2long($argv[1])===false?0:1);

ip2longはよく知られた組み込み関数です。



これは、新しいバージョンに存在するコード化されていない機能を使用しているようです(PHP7 +からのものと思われます)。PHP 4および5では、これは不完全なIPを受け入れることに注意してください。
イスマエルミゲル



1
1、2などの整数を入力すると、成功します。そうすべきではないと思います。また、100.100.100
nl-x

10

Perl 6の22 21 20バイト

Phil Hのおかげで-1バイト

{?/^@(^256)**4%\.$/}

オンラインでお試しください!

説明

{                  }  # Anonymous Block
  /               /   # Regex match
   ^             $    # Anchor to start/end
    @(    )           # Interpolate
      ^256            #   range 0..255,
                      #   effectively like (0|1|2|...|255)
           **4        # Repeated four times
              %\.     # Separated by dot
 ?                    # Convert match result to Bool

3
男、Perl 6の正規表現を理解するのにもっと時間をかける必要があります。%修飾子も存在しませんでした。すべての256**4可能性をチェックしようとするのだろうか?
ジョーキング

1
代わりに<{^256}>、範囲を@(^256)-1 char TIOの配列に変換するだけです。コードブロックを配列に変更すると、非常に高速になります(30秒ではなく0.4秒)。
フィルH

@PhilHクール、ありがとう。試しました$(^256)が、なぜこれが機能しないのかがわかりました。
nwellnhof

9

05AB1E26 24 23 22 23 バイト

'.¡©g4Q₅Ý®å`®1šDïþJsJQP

@Emignaのおかげで-1バイト。
テストケースをバグ修正するための+1バイトは1.1.1.1E1、誤った結果を誤って返します。

オンラインそれを試してみたり、すべてのテストケースを確認してください

説明:

'.¡              '# Split the (implicit) input by "."
   ©              # Save it in the register (without popping)
    g4Q           # Check that there are exactly 4 numbers
    ₅Ý®å          # Check for each of the numbers that they are in the range [0,255],
        `         # and push the result for each number separated onto the stack
    ®1šDïþJsJQ    # Check that each number does NOT start with a "0" (excluding 0s itself),
                  # and that they consist of digits only
              P   # Check if all values on the stack are truthy (and output implicitly)

1
Ā代わりに使用できるようになります<d
Emigna

@MagicOctopusUrn私はそれがために失敗した怖い1.1.1.1E11..1.1.11.1.1.1.192.00.0.255、と0.00.10.255。(1.1.1.1E1追記:þ結合と同等のチェックにを追加することで修正しました。)
Kevin Cruijssen

まあ、私は何かを見逃したと思った。
魔法のタコ

@MagicOctopusUrn主な問題は05AB1Eであり、先頭に0が付いている数字が、文字列としても数字がない場合と同じです。これは私が使用する理由であるDïþJsJQチェックï有数の0を削除するにはint型にキャストし、þ唯一の葉のようなものを取り除く数字E-など、:) テストケース用で0.00.10.255、以来000102550010255等しくなります。
ケビンクルーッセン

ええ、私は同じナンセンスを経験しましたが、それらの場合を除いて、すべての数字の反転はかなりうまくいきました。いくつかの問題にとって有益な機能が他の機能にとってほとんどバグのようになるとき、興味深い。
魔法のタコ

6

PowerShell、59 51 49バイト

-8バイト、@ AdmBorkBorkに感謝

-2バイト、trueまたは作成者がfalse許可

try{"$args"-eq[IPAddress]::Parse($args)}catch{!1}

テストスクリプト:

$f = {

try{"$args"-eq[IPAddress]::Parse($args)}catch{!1}

}

@(
    ,("1.160.10.240" , $true)
    ,("192.001.32.47" , $false)
    ,("1.2.3." , $false)
    ,("1.2.3" , $false)
    ,("0.00.10.255" , $false)
    ,("192.168.1.1" , $true)
    ,("1.2.$.4" , $false)
    ,("255.160.0.34" , $true)
    ,(".1.1.1" , $false)
    ,("1..1.1.1" , $false)
    ,("1.1.1.-0" , $false)
    ,("1.1.1.+1" , $false)
    ,("1 1 1 1" , $false)
    ,("1"            ,$false)
    ,("10.300.4.0"   ,$false)
    ,("10.4F.10.99"  ,$false)
    ,("fruit loops"  ,$false)
    ,("1.2.3.4.5"    ,$false)

) | % {
    $s,$expected = $_
    $result = &$f $s
    "$($result-eq$expected): $result : $s"
}

出力:

True: True : 1.160.10.240
True: False : 192.001.32.47
True: False : 1.2.3.
True: False : 1.2.3
True: False : 0.00.10.255
True: True : 192.168.1.1
True: False : 1.2.$.4
True: True : 255.160.0.34
True: False : .1.1.1
True: False : 1..1.1.1
True: False : 1.1.1.-0
True: False : 1.1.1.+1
True: False : 1 1 1 1
True: False : 1
True: False : 10.300.4.0
True: False : 10.4F.10.99
True: False : fruit loops
True: False : 1.2.3.4.5

説明:

スクリプトは、引数文字列を解析して、.NETオブジェクトIPAddressを構築しようとします。

  • 作成され、引数文字列が(による正規化されたアドレス)の文字列表現と等しい$true場合に返しますobjectobjectobject.toString()
  • $falseそうでなければ戻る

PowerShell、59 56 54バイト、「。NET libを使用しない」代替

-3バイト、trueまたは作成者がfalse許可

-2バイト。クールな正規表現の@ Deadcodeに感謝します。

".$args"-match'^(\.(2(?!5?[6-9])|1|(?!0\B))\d\d?){4}$'

オンラインでお試しください!

元の正規表現をありがとう@ OlivierGrégoire


1
左側は文字列であるため、|% t*gPowerShellは右側を-eq文字列として自動的にキャストするため、呼び出す必要はありません。-try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
AdmBorkBork

私の正規表現を使用して、「。NET libを使用しない」バージョンから2バイトを切り分けることができます(純粋な正規表現であるため、このバージョンには含まれないピリオド挿入トリックに適応)。tio.run/...
Deadcode

5

C(gcc) / POSIX、26バイト

f(s){s=inet_pton(2,s,&s);}

オンラインでお試しください!

TIOでは64ビットコードとして機能しますがsizeof(int) == sizeof(char*)、他のプラットフォームではおそらくそれが必要です。


@TobySpeight Yes, if you're on x86, you should probably try in 32-bit mode (-m32).
nwellnhof

I got it to work, by passing s as a char* (no access to a ILP32 system here), and yes, I was mixing up with inet_aton().
Toby Speight

5

PHP 7+, 37 35 32 bytes

This uses the builtin function filter_var, to validate that it is an IPv4 address.

For it to work, you need to pass the key i over a GET request.

<?=filter_var($_GET[i],275,5**9);

Will output nothing (for a falsy result) or the IP (for a truthy result), depending on the result.

You can try this on: http://sandbox.onlinephpfunctions.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfunctions.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


This uses the following values directly:

  • 275 = FILTER_VALIDATE_IP
  • 1<<20 = 1048576 = FILTER_FLAG_IPV4
  • 5**9 = 1953125 (which has the required bit as "1", for 1048576)

Thank you to Benoit Esnard for this tip that saved me 1 byte!

Thank you to Titus for reminding me of the changes to the challenge.


I've looked into using the function ip2long, but it works with non-complete IP addresses.

Non-complete IPv4 addresses are considered invalid in this challenge.

If they were allowed, this would be the final code (only for PHP 5.2.10):

<?=ip2long($_GET[i]);

Currently, it isn't explicit in the documentation that this will stop working (when passed an incomplete ip) with newer PHP versions.

After testing, confirmed that that was the case.

Thanks to nwellnhof for the tip!


Using 5**9 instead of 1<<20 saves one byte here: PHP uses & to test the IPv4 / IPv6 flags, so any number between 1048576 and 2097151 is valid.
Benoit Esnard

In newer PHP versions, ip2long doesn't allow incomplete addresses.
nwellnhof

@BenoitEsnard Thank you! I've added it to the answer
Ismael Miguel

@nwellnhof After testing, I confirm that that is the case. However, I don't think it is a good idea to use it, since it isn't explicitly documented.
Ismael Miguel

+!! is not required; the OP now accepts arbitrary truthy values.
Titus

5

Python 3: 81 78 70 69 66 bytes

['%d.%d.%d.%d'%(*x.to_bytes(4,'big'),)for x in range(16**8)].count

Loop over all possible IPv4 addresses, get the string representation and compare it to the input. It uh... takes a while to run.

EDIT: Removed 3 bytes by switching from full program to anonymous function.

EDIT2: Removed 8 bytes with help from xnor

EDIT3: Removed 1 byte by using an unpacked map instead of list comprehension

EDIT4: Removed 3 bytes by using list comprehension instead of the ipaddress module


2
I think your anonymous function can just be [str(ip_address(x))for x in range(256**4)].count. Also, 256**4 can be 16**8.
xnor

5

C# (Visual C# Interactive Compiler), 84 79 65 bytes

s=>s.Split('.').Sum(t=>byte.TryParse(t,out var b)&t==b+""?1:5)==4

Try it online!

-5 and -14 bytes saved thanks to @dana!

# C# (Visual C# Interactive Compiler), 61 bytes

s=>s.Count(c=>c==46)==3&IPAddress.TryParse(s,out IPAddress i)

Try it online!

This is a work in progress. The code use System.Net (+17 bytes if you count it). if you wonder why I count and parse:

The limitation with IPAddress.TryParse method is that it verifies if a string could be converted to IP address, thus if it is supplied with a string value like "5", it consider it as "0.0.0.5".

source

As @milk said in comment, it will indeed fail on leading zeroes. So, the 61 bytes one is not working.


1
@dana great. Nicely done! Four more and it will beat the 61 bytes solutions!
aloisdg says Reinstate Monica

4

Python 2, 85 82 81 bytes

-1 byte thanks to Kevin Cruijssen

from ipaddress import*
I=input()
try:r=I==str(IPv4Address(I))
except:r=0
print~~r

Try it online!

113 byte answer is deleted as it fails for 1.1.1.1e-80


1
You can golf print 1*r to print~~r. +1 though, since it seem to work for all possible test cases suggested thus far. PS: Your 113 byte answer fails for 1.1.1.1e-80.
Kevin Cruijssen

@KevinCruijssen Thanks! Didn't think about such notation of numbers
Dead Possum

Isn't ipaddress a Python 3 module?
Farhan.K

@Farhan.K Dunno, but it works in TIO
Dead Possum

4

Japt, 17 15 bytes

q.
ʶ4«Uk#ÿòs)Ê

Try it or run all test cases or verify additional test cases from challenge comments


Explanation

We split to an array on ., check that the length of that array is equal to 4 AND that the length when all elements in the range ["0","255"] are removed from it is falsey (0).

                 :Implicit input of string U
q.               :Split on "."
\n               :Reassign resulting array to U
Ê                :Length of U
 ¶4              :Equals 4?
   «             :&&!
    Uk           :Remove from U
      #ÿ         :  255
        ò        :  Range [0,255]
         s       :  Convert each to a string
          )      :End removal
           Ê     :Length of resulting array

Nice answer. Also verified for all suggested test cases thus far. Curious to see that explanation.
Kevin Cruijssen

2
@KevinCruijssen, explanation added. Thanks for those additional test cases.
Shaggy

3

Mathematica, 39 31 bytes

Original version:

¬FailureQ[Interpreter["IPAddress"][#]]&

Modified version (thanks to Misha Lavrov)

 AtomQ@*Interpreter["IPAddress"]

which returns True if the input is a valid IP address (try it).

In case you insist on getting 1 and 0 instead, then an additional 7 bytes would be necessary:

Boole/@AtomQ@*Interpreter["IPAddress"]

Since Interpreter["IPAddress"] returns a string for valid input, and some complicated failure object for invalid input, we can test for valid inputs with AtomQ[Interpreter["IPAddress"][#]]&, which can be further shortened to the function composition AtomQ@*Interpreter["IPAddress"]. Try it online!
Misha Lavrov

Fails on an IPv6 address like 2001:0db8:85a3:0000:0000:8a2e:0370:7334.
lirtosiast


3

Python 2, 93 89 67 53 bytes

[i==`int(i)&255`for i in input().split('.')]!=[1]*4>_

Try it online!

Thanks to Dennis for shaving another 14 bytes on the internal comparisons and exit code.

Special thanks to Jonathan Allan for shaving 22 bytes & a logic fix! Pesky try/except begone!

Taking properly formatted strings instead of raw bytes shaves off 4 bytes, thanks Jo King.


Your check can be golfed to i==`int(i)&255` . Also, you can force an error with [...]!=[1]*4>_, since you're using exit codes anyway. Try it online!
Dennis

@Dennis I don't understand what >_ does. The bitwise and is quite ingenious though... I was unsuccessful in combining those myself.
TemporalWolf

2
If the != returns False, Python short-circuits and nothing happens; the interpreter exits normally. If it returns True, >_ raises a NameError, because the variable _ is undefined.
Dennis

Figures I chain comparisons in my answer and then miss the obvious result in your comment. Thanks for the explanation.
TemporalWolf

3

sfk, 176 bytes

* was originally Bash + SFK but TIO has since added a proper SFK wrapper

xex -i "_[lstart][1.3 digits].[1.3 digits].[1.3 digits].[1.3 digits][lend]_[part2]\n[part4]\n[part6]\n[part8]_" +xed _[lstart]0[digit]_999_ +hex +linelen +filt -+1 -+2 +linelen

Try it online!


Would first checking the error printout from nc [addr] 1 -w1 shorten this?

@Rogem nc accepts leading zeroes as well as IPv6 addresses, so I'd still have to handle those - and this is intended more as a sfk answer than a shell answer anyway.
Οurous

3

Python3 Bash* 60

*Also other shells. Any one for which the truthy/falsy test passes on a program exit code

read I
python3 -c "from ipaddress import*;IPv4Address('$I')"

Explanation

The trouble with a pure Python solutions is that a program crashing is considered indeterminate. We could use a "lot" of code to convert an exception into a proper truthy/fasly value. However, at some point the Python interpreter handles this uncaught exception and returns a non-zero exit code. For the low-low cost of changing languages to your favourite Unix shell, we can save quite a bit of code!

Of course, this is vulnerable to injection attacks... Inputs such as 1.1.1.1'); print('Doing Something Evil are an unmitigated threat!


(Explanation it is (not Explaination).)
Peter Mortensen

@PeterMortensen Yikes. It was even underlined in red. My browser tried to save me, but I wouldn't listen. Thanks for catching that!
Sompom

Full programs are allowed to output via exit codes, therefore this could be 43 bytes.
ბიმო

@BMO Interesting. Thanks for pointing that out! I think the problem definiiton changed from "Truthy/Falsy" to also allowing arbitrary output since I posted this, but I could have just not noticed before :)
Sompom

3

ECMAScript pure regex, 41 bytes

^((2(?!5?[6-9])|1|(?!0\B))\d\d?\.?\b){4}$

Try it online!
Try it on regex101

I think the logic in this regex speaks for itself, so I will merely pretty-print but not comment it:

^
(
    (
        2(?!5?[6-9])
    |
        1
    |
        (?!0\B)
    )
    \d\d?
    \.?\b
){4}
$

This can be used to shave 2 bytes off the following other answers:

Here is an alternative version that allows leading zeros, but does so consistently (octets may be represented by a maximum of 3 decimal digits):

^((2(?!5?[6-9])|1|0?)\d\d?\.?\b){4}$

Or allow any number of leading zeros:

^(0*(2(?!5?[6-9])|1?)\d\d?\.?\b){4}$


1
\b and \B... it's smart!
mazzy

1
@mazzy Yes, those two really come in handy! I could've used (?!0\d) instead, but I like \B better!
Deadcode

The powershell answer doesn't get shorter with your regexp. I'm sorry. Quotes are needed to convert an array to a string. Try it online!
mazzy

1
The \.?\b saved me a byte on my answer too, thanks!
Neil

1
Saved 3 bytes thx
l4m2

2

Red, 106 bytes

func[s][if error? try[t: load s][return off]if 4 <> length? t[return off]s =
form as-ipv4 t/1 t/2 t/3 t/4]

Try it online!

Returnd true or false

Explanation:

f: func [ s ] [
    if error? try [                  ; checks if the execution of the next block result in an error
        t: load s                    ; loading a string separated by '.' gives a tuple   
    ] [                              ; each part of which must be in the range 0..255
        return off                   ; if there's an error, return 'false' 
    ]
    if 4 <> length? t [              ; if the tuple doesn't have exactly 4 parts
        return off                   ; return 'false'  
    ]
    s = form as-ipv4 t/1 t/2 t/3 t/4 ; is the input equal to its parts converted to an IP adress
]

2

Stax, 14 bytes

∞n·Θ3ª&JH‼∙*~Γ

Run and debug it

Unpacked, ungolfed, and commented, it looks like this.

VB      constant 256
r       [0 .. 255]
'|*     coerce and string-join with "|"; i.e. "0|1|2|3 ... 254|255"
:{      parenthesize to "(0|1|2|3 ... 254|255)"
]4*     make 4-length array of number pattern
.\.*    string join with "\\."; this forms the complete regex
|Q      is the input a complete match for the regex?

Run this one


Surprised to know that you made the language Stax! it is working well.
rv7

Thanks! The space of golfing languages is surprisingly crowded, and I'm not sure if stax can justify its own existence on its merits, but my main goal was just to see if I could do it and maybe learn something. It ended up being more fun than expected.
recursive

2

Python 3, 109 93 bytes

import re
lambda x:bool(re.match(r'^((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)(\.(?!$)|$)){4}$',x))

Explanation

Each octet can be 0 - 255 :

  • starts with 25 and having 0-5 as last digit
  • start with 2, has 0-4 as second digit and any digit at the end
  • starts with 1, and 00 - 99 as rest digits
  • has only 2 digits - 1-9 being the first one and any digit thereafter
  • or just a single digit

An octet can end with a (.) or just end, with the condition that it cannot do both , the negative lookahead (?!$) takes care of this case

Thanks @Zachary for making me realize I can discard spaces (since it is code golf)
Thanks @DLosc for the improvements and making me realize my mistake, its been corrected now.


2
Some explanation for this might help.
Nissa

x: re.match=>x:re.match; , x => ,x, and ) is => )is should save 3 bytes. Also, in the regex, you can use \d for each occurrence of [0-9], and [1]=>1. This seems like a great first post, though!
Zacharý

[1-9][0-9]|[0-9] can become [1-9]\d|\d (per Zacharý's advice), which can become [1-9]?\d. Also, instead of testing re.match(...)is not None, you can do bool(re.match(...)) since match objects are truthy and None is falsey. :)
DLosc

Hmm. Actually, this fails on the test case 1.2.3.4.5 (and also 1.2.3.4., which isn't in the official list of test cases), because it can match a period instead of end-of-string after the fourth number.
DLosc


2

Charcoal, 45 21 bytes

I∧⁼№θ.³¬Φ⪪θ.¬№E²⁵⁶Iλι

Try it online! Link is to verbose version of code. Edit: Saved 24 bytes by porting @Shaggy's Japt answer. Explanation:

    θ                   Input string
   №                    Count occurrences of
     .                  Literal `.`
  ⁼                     Equal to
      ³                 Literal 3
 ∧                      Logical And
       ¬                Logical Not
          θ             Input string
         ⪪              Split on
           .            Literal `.`
        Φ               Filter by
            ¬           Logical Not
               ²⁵⁶      Literal 256
              E         Map over implicit range
                   λ    Map value
                  I     Cast to string
             №          Count occurrences of
                    ι   Filter value
I                       Cast to string
                        Implicitly print

Fails for test cases with negative integers like 123.-50.0.12 or 1.1.1.-80. Everything else seems to work fine. So the <256 check should be in [0,255] instead.
Kevin Cruijssen

@KevinCruijssen Actually the code to filter out invalid characters wasn't working because I forgot to change the variable in the inner loop. Should be fixed now.
Neil

2

Retina, 46 44 bytes

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

Port of @OlivierGrégoire's Java answer, so make sure to upvote him!
-2 bytes thanks to @Neil.

Try it online.

Explanation:

^
.                           # Prepend a dot "." before the (implicit) input
^...$                       # Check if the entire string matches the following regex
                            # exactly, resulting in 1/0 as truthy/falsey:
 (                          #  Open a capture group
  \.                        #   A dot "."
    (25[0-5]                #   Followed by a number in the range [250,255]
    |(2[0-4]|         ) \d) #   or by a number in the range [200,249]
    |(      |1\d|     ) \d) #   or by a number in the range [100,199]
    |(          |[1-9]) \d) #   or by a number in the range [10,99]
    |(                )?\d) #   or by a number in the range [0,9]
 )                          #  Close capture group
  {4}                       #  This capture group should match 4 times after each other

My attempt (which I didn't post because the question got put on hold at the time) was the same length, but didn't have the \d group optimisation, so you can save two bytes because you don't need the M specification on the last line.
Neil

I managed to get Retina down to 42 bytes by porting the Perl 6 answer but this answer also works in 0.8.2 which my port doesn't.
Neil

2

Jelly, 11 bytes

⁹ḶṾ€ṗ4j€”.ċ

A monadic link accepting a list of characters which yields 1 if it's a valid address and 0 otherwise. Builds a list of all 2564=4294967296 addresses and then counts the number of occurrences of the input therein.

Here's similar @ Try it online! that uses 16 () rather than 256 (), since the method is so inefficient!

How?

⁹ḶṾ€ṗ4j€”.ċ - Link: list of characters, S
⁹           - literal 256
 Ḷ          - lowered range = [0,1,2,...,254,255]
  Ṿ€        - unevaluate €ach = ['0','1',...,['2','5','4'],['2','5','5']]
    ṗ4      - 4th Cartesian power = ALL 256^4 lists of 4 of them
            -               (e.g.: ['0',['2','5','5'],'9',['1','0']])
        ”.  - literal '.' character
      j€    - join for €ach (e.g. ['0','.','2','5','5','.','9','.','1','0'] = "0.255.9.10")
          ċ - count occurrences of right (S) in left (that big list)

Why does the version with 65,536 IPs take 1.8 seconds? o_O
Dennis

2

Retina, 42 41 bytes

~(K`

255*
["^(("|'|]")\.?\b){4}$"L$`
$.`

Try it online! Based on a previous version of @nwellnhof's Perl 6 answer, but 1 byte saved by stealing the \.?\b trick from @Deadcode's answer. Explanation:

K`

Clear the work area.

255*

Insert 255 characters.

["^(("|'|]")\.?\b){4}$"L$`
$.`

Generate the range 0..255 separated with |s, prefixed with ^((, and suffixed with )\.?\b){4}$, thus building the regular expression ^((0|1|...255)\.?\b){4}$.

~(

Evaluate that on the original input.


1

Pip, 25 16 bytes

a~=X,256RL4J"\."

Takes the candidate IP address as a command-line argument. Try it online! or Verify all test cases

Explanation

Regex solution, essentially a port of recursive's Stax answer.

                  a is 1st cmdline arg (implicit)
    ,256          Range(256), i.e. [0 1 2 ... 255]
   X              To regex: creates a regex that matches any item from that list
                  i.e. essentially `(0|1|2|...|255)`
        RL4       Create a list with 4 copies of that regex
           J"\."  Join on this string
 ~=               Regex full-match
a                 against the input

1

JavaScript, 89 bytes

(_,r=`(${[...Array(256).keys()].join`|`})`)=>RegExp(`^${(r+'\\.').repeat(3)+r}$`).test(_)

Try it online!

Create RegExp capture groups from indexes of an array having length 256 for range 0-255 joined with | and followed by escaped . character (^(0|1...|255)\.(0|1...|255)\.(0|1...|255)\.(0|1...|255)$) repeated 3 times closing with joined array followed by $ to match end of string, return true or false result of input passed to RegExp.prototype.test().

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.