Alamat IP atau tidak?

25

Alat pemindaian jaringan Anda sangat pemilih dalam hal input, dan segera macet jika Anda memasukkannya ke alamat IPv4 yang berisi karakter yang tidak pantas atau tidak diformat dengan benar.

Alamat IPv4 adalah alamat numerik 32-bit yang ditulis sebagai empat angka yang dipisahkan oleh titik. Setiap angka bisa nol hingga 255 .

Kita perlu menulis alat untuk memvalidasi input sebelum menghindari crash itu, dan alat khusus kita pilih-pilih: Format yang valid akan terlihat seperti di a.b.c.dmana a, b, c dan d:

  • Dapat berupa 0angka alami atau tanpa nol di depan .
  • Harus antara 0 - 255 (inklusif).
  • Harus tidak mengandung simbol-simbol khusus seperti +, -, ,, dan lain-lain.
  • Harus berupa desimal (basis 10)

Input : String

Output : Nilai Truthy atau Falsey (nilai arbitrer juga diterima)

Kasus uji :

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)

Ini adalah , sehingga byte paling sedikit akan menang!

Catatan untuk pengguna - jika Anda ingin menambahkan beberapa lagi kasus uji, Anda disambut (dengan menyarankan edit). Tapi, tolong pastikan bahwa test case tidak terulang! Terima kasih

rv7
sumber
10
Sarankan testcases: 1.1.1.1.1, 1.1.1.1., .1.1.1, 1..1.1, 1..1.1.1, 1.1.1.0, 1.1.1.-0, 1.1.1.+1, 1.1.1.1E1, 1.1.1.256, 1.1.1.0x1, 255.255.255.255, 0.0.0.0, 'or 1=1--, <empty string>, 1 1 1 1, 1,1,1,1.
tsh
5
Sarankan menambahkan test case "1.2.3.4.5" (untuk mengesampingkan IP yang terlalu panjang) dan "999.0.0.0" (untuk mengesampingkan IP yang terlalu besar).
Triggernometri
5
Mungkin sedikit pilih-pilih, tetapi Anda mungkin harus merujuk ke "alamat IPv4" daripada "alamat IP" - atau setidaknya, sebutkan di suatu tempat yang Anda maksudkan alamat IPv4 - jika tidak 1234: 5678 :: 1 seharusnya alamat IP yang valid (sedangkan dari uraian jelas bahwa itu tidak dimaksudkan :)
psmears
3
@Criggie Dasarnya bukan untuk benar - benar memeriksa semua aturan IP4 nyata (seperti yang Anda sebutkan), itu untuk memastikan bahwa string input tidak menabrak beberapa aplikasi lain (mungkin ditulis dengan buruk) yang hanya memungkinkan input dalam bentuk yang sangat spesifik . Juga, kita tidak akan mengubah aturan tantangan yang sudah memiliki 30+ jawaban.
BradC
2
@Criggie Layak dicatat bahwa RFC menyatakan bahwa "Alamat memiliki panjang tetap empat oktet". Saya pikir kasus pinggiran yang Anda rujuk lebih terspesialisasi daripada tantangan ini.
Poke

Jawaban:

26

Kode mesin X86_64: 18 16 byte

Sunting: Jawaban ini tidak cukup berhasil, karena

  1. Saya menggunakan inet_ptondari pustaka C standar, yang berarti saya perlu eksternal. Saya tidak memasukkan extern dalam hitungan byte saya.
  2. Saya menggunakan zona merah sebagai hasil untuk alamat aktual, tetapi memanggil fungsi yang juga bisa menggunakan zona merah. Untungnya tidak ada di komputer saya, tetapi beberapa bangunan perpustakaan standar yang aneh mungkin menggunakannya yang dapat menyebabkan perilaku yang tidak jelas.

Dan ya, semuanya cukup banyak dilakukan oleh fungsi yang sudah ditulis

Bagaimanapun, inilah yang saya dapat: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

Majelis:

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

Penjelasan:

Lihatlah inet_pton(3). Dibutuhkan alamat IP string dan memasukkannya ke dalam buffer yang dapat Anda gunakan struct sockaddr. Dibutuhkan 3 argumen: keluarga alamat ( AF_INET(ipv4), 2, atau AF_INET6(ipv6), 10), string alamat ip, dan pointer ke output. Ini mengembalikan 1 pada keberhasilan, 0 untuk alamat yang tidak valid, atau -1 untuk ketika keluarga alamat tidak AF_INETatau AF_INET6(yang tidak akan pernah terjadi karena saya memberikan konstanta untuk itu).

Jadi saya cukup memindahkan string ke register untuk argumen kedua, mengatur register pertama ke 2, dan mengatur register ketiga ke zona merah (128 byte di bawah stack pointer) karena saya tidak peduli dengan hasilnya. Maka saya bisa langsung jmpke inet_ptondan membiarkan itu kembali langsung ke penelepon!

Saya memutar program uji cepat ini untuk menguji kasus Anda:

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

Berkumpul dengan nasm -felf64 assembly.asm, kompilasi dengan gcc -no-pie test.c assembly.o, dan Anda akan mendapatkan:

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

Saya bisa membuat ini jauh lebih kecil jika penelepon seharusnya lulus AF_INETatau AF_INET6ke fungsi

pengguna233009
sumber
4
Saya suka Anda melakukan ini di ASM. Dan fakta yang Anda jelaskan kepada mereka yang mungkin tidak memahaminya (juga kode uji) bahkan lebih baik. Bukan berarti saya bisa melakukannya dalam asm; Sudah bertahun-tahun berlalu, tetapi saya cukup ingat untuk melihat dengan tepat apa yang dikatakan oleh penjelasan Anda (dan karena itu proses). Kerja bagus.
Pryftan
4
e9 00 00 00 00adalah a jmp near $+5, bukan a jmp inet_pton. Jika Anda memberikan opcode, Anda harus memasukkan bagian yang disertakan inet_pton, jangan biarkan kosong
l4m2
1
15 bytes-TIO 32bit x86
Logern
3
Anda harus memasukkan eksternal dalam judul jawaban, karena program membutuhkannya dan tidak tersedia di semua platform.
qwr
1
"mov rdi, 2" dapat "push 2 / pop rdi" untuk -2 byte. Perhatikan juga bahwa pembongkaran salah atau kode salah. Entah "mov edi" (bukan rdi) atau ada awalan yang hilang.
peter ferrie
13

Java (JDK) , 63 byte

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

Cobalah online!

Kredit

  • -1 byte terima kasih kepada Kevin Cruijssen
  • 14m2 untuk menunjukkan kasus yang sebelumnya gagal .1.1.1.1.
Olivier Grégoire
sumber
Anda lupa menghapus tanda titik koma. ;) Dan saya dapat memverifikasi itu berfungsi untuk semua kasus uji, termasuk yang ada di komentar. Akan melihat apakah saya melihat beberapa hal untuk golf.
Kevin Cruijssen
3
Gagal.1.2.3.4
14m2
Apakah diizinkan menggunakan boolean ketika secara eksplisit membutuhkan 0/1?
14m2
1
@ l4m2 Pertanyaan aslinya adalah Valid / Tidak Valid. Jadi saya menganggap nilai kebenaran / falsey dapat diterima di sini.
Kevin Cruijssen
Output: 0 or 1dan Java tidak memiliki auto bool-> int
l4m2
12

JavaScript (Node.js) , 43 byte

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

Cobalah online!

JavaScript (Node.js) , 46 byte

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

Cobalah online!

menggunakan bagian Arnauld

JavaScript (Node.js) , 54 53 51 byte

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

Cobalah online!

-2B untuk 0+t<256, -1B dari Patrick Stephansen, + 1B untuk menghindari input1.1.1.1e-80

Solusi RegExp 58 54 byte

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

Terima Deadcode selama 3 byte

l4m2
sumber
Saya telah menambahkan beberapa test case!
rv7
Ini memberi kebenaran untuk 0.0.0.0. Segala sesuatu yang lain tampaknya bekerja dengan baik.
Kevin Cruijssen
1
@KevinCruijssen 0.0.0.0ada di sini yang benar. Kenapa injeksi SQL ada di sini?
14m2
Ah tunggu, saya salah mengartikan kalimat dalam deskripsi tantangan. 0.0.0.0memang benar. Itu kehendak golf jawaban saya juga .. (? Dan apa yang Anda maksud dengan SQL injection: S link adalah untuk TIO dengan SEMUA uji kasus.)
Kevin Cruijssen
1
@ l4m2 Saya menambahkannya karena kami membutuhkan beberapa testcases yang bahkan tidak terlihat seperti alamat IP.
tsh
11

PHP , 39 36 byte

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

Cobalah online!

275 menyerupai konstanta FILTER_VALIDATE_IP

5 ** 9 digunakan sebagai pengganti konstanta FILTER_FLAG_IPV4. Ini sudah cukup, karena 5**9 & FILTER_FLAG_IPV4ini benar, yang persis seperti yang dilakukan PHP di latar belakang, seperti yang ditunjukkan Benoit Esnard.

Di sini, filter_varkembalikan argumen pertama, apakah itu alamat IPv4 yang valid, atau salah jika tidak. Dengan +!!, kami menghasilkan output yang dibutuhkan oleh tantangan.

oktupol
sumber
3
Menggunakan 5**9alih-alih 1048576menyimpan 3 byte di sini: PHP digunakan &untuk menguji flag IPv4 / IPv6 , sehingga angka apa pun antara 1048576 dan 2097151 valid.
Benoit Esnard
Saya dengan ini menurunkan jawaban Anda untuk menjadi (pada dasarnya) jawaban saya: codegolf.stackexchange.com/a/174470/14732 yang ditulis pada 2018-10-22 09: 17: 34UTC sementara jawaban Anda ditulis pada 2018-10-22 09: 21: 55UTC. Bahkan jika saya mengembalikan optimasi 1-byte yang diberikan oleh @BenoitEsnard, jawaban saya persis sama dengan Anda dalam fungsionalitas.
Ismael Miguel
2
Saya harus minta maaf, saya tidak melihat jawaban Anda, meskipun pada saat saya menyusunnya, tidak ada pengajuan dalam PHP pada pertanyaan ini (seperti yang Anda katakan, perbedaan waktu kurang dari lima menit).
oktupol
Saya tahu, dan saya memahaminya. Saya hanya memperhatikan milik Anda sekarang. Saya dapat memutar kembali milik saya, dan Anda tetap optimasi. Tapi saya tidak tahu apakah itu membuat jawabannya cukup berbeda satu sama lain.
Ismael Miguel
17
@ IsmaelMiguel Saya tidak akan menurunkan suara seseorang untuk itu jika Anda masuk akal tidak ada ketika mereka mulai. Dengan perbedaan 5 menit, tidak hanya masuk akal, itu hampir pasti terjadi, yang jelas bahkan tanpa penulis mengatakannya sendiri.
Duncan X Simpson
11

PHP, 36 Bytes

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

ip2longadalah terkenal built-in fungsi .

rexkogitans
sumber
3
29 byte
nwellnhof
Ini tampaknya menggunakan fitur tidak berdokumen yang ada dalam versi yang lebih baru (saya kira itu dari PHP7 +). Perlu diingat bahwa, untuk PHP 4 dan 5, ini memang menerima IP yang tidak lengkap.
Ismael Miguel
27 byte
Tandai
1
Ini akan memberikan kesuksesan jika Anda memberinya bilangan bulat apa pun, seperti 1, 2, dll. Jangan berpikir itu seharusnya. Dan juga jika Anda memberinya makan 100.100.100
nl-x
10

Perl 6 , 22 21 20 byte

-1 byte terima kasih kepada Phil H.

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

Cobalah online!

Penjelasan

{                  }  # 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
nwellnhof
sumber
3
Sobat, aku harus menghabiskan lebih banyak waktu mencari tahu regex Perl 6. Saya tidak memiliki %modifikator. Saya ingin tahu apakah ia mencoba memeriksa semua 256**4kemungkinan?
Jo King
1
Alih-alih, <{^256}>Anda cukup mengonversi rentang ke array @(^256)untuk -1 char TIO . Dengan mengubah blok kode menjadi sebuah array, ia juga menjadi jauh lebih cepat (0,4 detik daripada> 30).
Phil H
@ Phil Cool, terima kasih. Saya mencoba $(^256)tetapi sekarang saya menyadari mengapa ini tidak berhasil.
nwellnhof
9

05AB1E , 26 24 23 22 23 byte

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

-1 byte terima kasih kepada @Emigna .
+1 byte untuk kasus uji perbaikan bug 1.1.1.1E1salah mengembalikan hasil yang benar.

Cobalah online atau verifikasi semua kasus uji .

Penjelasan:

'.¡              '# 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)
Kevin Cruijssen
sumber
1
Anda harus dapat menggunakan Āsebagai gantinya<d
Emigna
@MagicOctopusUrn Aku takut gagal untuk 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255, dan 0.00.10.255. (PS: Saya sudah memperbaikinya 1.1.1.1E1dengan menambahkan þcek bergabung-dan-sama.)
Kevin Cruijssen
Cukup adil, kupikir aku melewatkan sesuatu.
Magic Gurita Guci
@MagicOctopusUrn Masalah utamanya adalah 05AB1E melihat angka dengan 0s sama dengan yang tanpa, bahkan sebagai string. Itulah sebabnya saya menggunakan DïþJsJQcek mana ïdilemparkan ke int untuk menghapus 0s terkemuka, dan þhanya daun digit menghapus hal-hal seperti E, -, dll :) The adalah untuk kasus uji 0.00.10.255, karena 00010255dan 0010255akan sama.
Kevin Cruijssen
Ya saya melewati omong kosong yang sama, pembalikan semua angka bekerja dengan cukup baik, kecuali untuk kasus-kasus itu. Menarik ketika fitur yang bermanfaat untuk beberapa masalah menjadi hampir seperti bug untuk orang lain.
Magic Octopus Guci
6

PowerShell, 59 51 49 byte

-8 byte, terima kasih @AdmBorkBork

-2 byte, trueatau falsediizinkan oleh penulis

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

Skrip uji:

$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"
}

Keluaran:

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

Penjelasan:

Script mencoba mengurai string argumen, untuk membangun objek .NET, IPAddress .

  • kembali $truejika objectdibuat dan argumen string sama dengan representasi string dari object(alamat dinormalisasi oleh object.toString())
  • kembali $falsesebaliknya

PowerShell, 59 56 54 byte, 'jangan gunakan alternatif .NET lib'

-3 byte, trueatau falsediizinkan oleh penulis

-2 byte, terima kasih kepada @ Deadcode untuk regexp keren.

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

Cobalah online!

Terima kasih @ Olivier Grégoire untuk ekspresi reguler yang asli.

mazzy
sumber
1
Anda tidak perlu menelepon |% t*gkarena PowerShell akan secara otomatis memasukkan sisi kanan -eqsebagai string, karena sisi kiri adalah string. -try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
AdmBorkBork
Anda dapat mengukir 2 byte dari versi "jangan gunakan .NET lib" dengan menggunakan regex saya (disesuaikan dengan trik insert-a-period, yang tentu saja tidak bisa dalam versi saya karena ini adalah regex murni): tio.run/…
Deadcode
5

C (gcc) / POSIX, 26 byte

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

Cobalah online!

Bekerja sebagai kode 64-bit pada TIO tetapi mungkin mengharuskannya sizeof(int) == sizeof(char*)pada platform lain.

nwellnhof
sumber
@TobySpeight Ya, jika Anda menggunakan x86, Anda mungkin harus mencoba dalam mode 32-bit ( -m32).
nwellnhof
Saya berhasil, dengan melewati ssebagai char*(tidak ada akses ke sistem ILP32 di sini), dan ya, saya bergaul dengan inet_aton().
Toby Speight
5

PHP 7+, 37 35 32 byte

Ini menggunakan fungsi builtin filter_var, untuk memvalidasi bahwa itu adalah alamat IPv4 .

Agar bisa berfungsi, Anda harus melewati kunci iatas permintaan GET.

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

Akan menghasilkan apa-apa (untuk falsyhasil) atau IP (untuk truthyhasil), tergantung pada hasilnya.

Anda dapat mencoba ini di: http://sandbox.onlinephpfunctions.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfunctions.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


Ini menggunakan nilai berikut secara langsung:

  • 275 = FILTER_VALIDATE_IP
  • 1 << 20 = 1048576 = FILTER_FLAG_IPV4
  • 5 ** 9 = 1953125 (yang memiliki bit yang diperlukan sebagai "1", untuk 1048576)

Terima kasih untuk Benoit Esnard atas tip ini yang menyelamatkan saya 1 byte!

Terima kasih kepada Titus karena mengingatkan saya tentang perubahan tantangan.


Saya sudah melihat ke dalam menggunakan fungsi ip2long , tetapi berfungsi dengan alamat IP yang tidak lengkap.

Alamat IPv4 yang tidak lengkap dianggap tidak valid dalam tantangan ini.

Jika diizinkan, ini akan menjadi kode final (hanya untuk PHP 5.2.10):

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

Saat ini, dalam dokumentasi tidak eksplisit bahwa ini akan berhenti berfungsi (ketika melewati ip yang tidak lengkap) dengan versi PHP yang lebih baru.

Setelah pengujian, mengkonfirmasi bahwa itulah masalahnya.

Terima kasih kepada nwellnhof untuk tipnya!

Ismael Miguel
sumber
Menggunakan 5**9alih-alih 1<<20menyimpan satu byte di sini: PHP digunakan &untuk menguji flag IPv4 / IPv6 , sehingga angka apa pun antara 1048576 dan 2097151 valid.
Benoit Esnard
Dalam versi PHP yang lebih baru, ip2longtidak mengizinkan alamat yang tidak lengkap.
nwellnhof
@BenoitEsnard Terima kasih! Saya telah menambahkannya ke jawabannya
Ismael Miguel
@nwellnhof Setelah pengujian, saya mengkonfirmasi bahwa itu masalahnya. Namun, saya tidak berpikir itu ide yang baik untuk menggunakannya, karena tidak didokumentasikan secara eksplisit.
Ismael Miguel
+!!tidak diperlukan; OP sekarang menerima nilai-nilai kebenaran yang sewenang-wenang.
Titus
5

Python 3: 81 78 70 69 66 byte

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

Ulangi semua alamat IPv4 yang mungkin, dapatkan representasi string dan bandingkan dengan input. Eh ... butuh beberapa saat untuk berlari.

EDIT: Dihapus 3 byte dengan beralih dari program penuh ke fungsi anonim.

EDIT2: Dihapus 8 byte dengan bantuan dari xnor

EDIT3: Dihapus 1 byte dengan menggunakan peta yang sudah dibongkar alih-alih pemahaman daftar

EDIT4: Dihapus 3 byte dengan menggunakan pemahaman daftar bukan ipaddressmodul

mypetlion
sumber
2
Saya pikir fungsi anonim Anda bisa saja [str(ip_address(x))for x in range(256**4)].count. Juga 256**4bisa 16**8.
xnor
5

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

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

Cobalah online!

-5 dan -14 byte disimpan berkat @dana!

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

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

Cobalah online!

Ini adalah pekerjaan yang sedang berjalan. Penggunaan kode System.Net(+17 byte jika Anda menghitungnya). jika Anda bertanya-tanya mengapa saya menghitung dan menguraikan:

Batasan dengan metode IPAddress.TryParse adalah bahwa ia memverifikasi jika string dapat dikonversi ke alamat IP, sehingga jika diberikan dengan nilai string seperti "5", itu menganggapnya sebagai "0.0.0.5".

sumber

Seperti yang dikatakan @milk dalam komentar, memang akan gagal memimpin nol. Jadi, 61 byte yang tidak berfungsi.

aloisdg kata Reinstate Monica
sumber
1
@dana bagus. Bagus sekali! Empat lagi dan itu akan mengalahkan solusi 61 byte!
aloisdg berkata Reinstate Monica
4

Python 2 , 85 82 81 byte

-1 byte terima kasih kepada Kevin Cruijssen

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

Cobalah online!

Jawaban 113 byte dihapus karena gagal1.1.1.1e-80

Possum Mati
sumber
1
Anda dapat golf print 1*rke print~~r. +1, karena tampaknya berfungsi untuk semua kasus uji yang disarankan sejauh ini . PS: Jawaban 113 byte Anda gagal 1.1.1.1e-80.
Kevin Cruijssen
@KevinCruijssen Terima kasih! Tidak memikirkan notasi angka seperti itu
Dead Possum
Bukankah ipaddressmodul Python 3?
Farhan.K
@ Farhan.K Entahlah, tetapi ia bekerja di TIO
Dead Possum
4

Japt, 17 15 byte

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

Cobalah atau jalankan semua test case atau verifikasi test case tambahan dari komentar tantangan


Penjelasan

Kami membagi ke array pada ., memeriksa bahwa panjang array itu sama dengan 4DAN bahwa panjang ketika semua elemen dalam rentang ["0","255"]dihapus dari itu adalah 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
Shaggy
sumber
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"]
polfosol ఠ_ఠ
sumber
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

JavaScript (ES6), 49 bytes

Returns a Boolean value.

s=>[0,1,2,3].map(i=>s.split`.`[i]&255).join`.`==s

Try it online!

Arnauld
sumber
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.

TemporalWolf
sumber
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!

Οurous
sumber
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!

Sompom
sumber
(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}$

Deadcode
sumber
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
]
Galen Ivanov
sumber
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

recursive
sumber
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.

alpheus
sumber
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

Bash, 30 bytes

ipcalc -c `cat`;echo $(($?^1))

Try it online!

Logern
sumber
The echo $(($?)) part is not needed since programs are allowed to output their result via exit code.
ბიმო
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
Neil
sumber
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
Kevin Cruijssen
sumber
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)
Jonathan Allan
sumber
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.

Neil
sumber
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
DLosc
sumber
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().

guest271314
sumber