Địa chỉ IP hay không?


25

Công cụ quét mạng của bạn rất khó chọn về đầu vào và ngay lập tức gặp sự cố nếu bạn cung cấp cho nó một địa chỉ IPv4 chứa các ký tự không chính xác hoặc không được định dạng chính xác.

Địa chỉ IPv4 là địa chỉ số 32 bit được viết dưới dạng bốn số cách nhau bởi dấu chấm. Mỗi số có thể từ 0 đến 255 .

Chúng ta cần viết một công cụ để xác thực trước đầu vào để tránh những sự cố đó và công cụ cụ thể của chúng tôi rất kén chọn: Một định dạng hợp lệ sẽ trông giống như a.b.c.dnơi a, b, c và d:

  • Có thể là một 0hoặc một số tự nhiên không có số 0 đứng đầu .
  • Nên từ 0 - 255 (đã bao gồm).
  • Nên không chứa các ký hiệu đặc biệt như +, -, ,, và những người khác.
  • Nên là số thập phân (cơ sở 10)

Đầu vào : Một chuỗi

Đầu ra : Giá trị Truthy hoặc Falsey (giá trị tùy ý cũng được chấp nhận)

Các trường hợp thử nghiệm :

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)

Đây là , vì vậy ít byte nhất sẽ giành chiến thắng!

Lưu ý cho người dùng - nếu bạn muốn thêm một số trường hợp thử nghiệm khác, bạn được hoan nghênh (bằng cách đề xuất chỉnh sửa). Nhưng, hãy chắc chắn rằng các trường hợp thử nghiệm không lặp lại! Cảm ơn


10
Đề nghị 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
Đề xuất thêm các trường hợp kiểm tra "1.2.3.4.5" (để loại trừ IP quá dài) và "999.0.0.0" (để loại trừ IP quá lớn).
Triggernometry 22/10/18

5
Có thể hơi kén chọn, nhưng có lẽ bạn nên tham khảo "địa chỉ IPv4" thay vì "địa chỉ IP" - hoặc ít nhất, đề cập đến một nơi nào đó mà bạn chỉ có nghĩa là địa chỉ IPv4 - nếu không thì 1234: 5678 :: 1 phải là địa chỉ IP hợp lệ (trong khi đó từ mô tả rõ ràng là không có ý định :)
psmears

3
@Criggie Tiền đề không thực sự kiểm tra tất cả các quy tắc IP4 thực (như các quy tắc bạn đã đề cập), để đảm bảo rằng chuỗi đầu vào không gặp sự cố với một số ứng dụng khác (có lẽ được viết xấu) chỉ cho phép nhập vào ở dạng rất cụ thể . Ngoài ra, chúng tôi sẽ không thay đổi các quy tắc của một thử thách đã có hơn 30 câu trả lời.
BradC

2
@Criggie Đáng lưu ý rằng RFC tuyên bố rằng "Địa chỉ có độ dài cố định là bốn octet". Tôi nghĩ rằng các trường hợp bên lề bạn tham khảo là chuyên ngành hơn thách thức này.
Chọc

Câu trả lời:


26

Mã máy X86_64: 18 16 byte

Chỉnh sửa: Câu trả lời này không hoạt động, như

  1. Tôi đang sử dụng inet_ptontừ các thư viện C tiêu chuẩn, có nghĩa là tôi cần extern. Tôi đã không bao gồm extern trong số byte của tôi mặc dù.
  2. Tôi đã sử dụng vùng màu đỏ làm kết quả cho địa chỉ thực tế, nhưng được gọi là hàm cũng có thể sử dụng vùng màu đỏ. Nó may mắn không có trên máy của tôi, nhưng một số bản dựng thư viện tiêu chuẩn kỳ quặc có thể sử dụng nó có thể gây ra hành vi không xác định.

Và vâng, toàn bộ điều này được thực hiện khá nhiều bởi một chức năng đã được viết

Dù sao, đây là những gì tôi nhận được: 48 89 fe 6a 02 5f 48 8d 54 24 80 e9 00 00 00 00

Hội,, tổ hợp:

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

Giải trình:

Hãy nhìn vào inet_pton(3). Nó nhận một địa chỉ IP chuỗi và đặt nó vào một bộ đệm mà bạn có thể sử dụng struct sockaddr. Phải mất 3 đối số: họ địa chỉ ( AF_INET(ipv4), 2 hoặc AF_INET6(ipv6), 10), chuỗi địa chỉ ip và một con trỏ tới đầu ra. Nó trả về 1 khi thành công, 0 cho một địa chỉ không hợp lệ hoặc -1 cho khi họ địa chỉ không AF_INEThoặc AF_INET6(điều này sẽ không bao giờ xảy ra vì tôi truyền hằng số cho nó).

Vì vậy, tôi chỉ cần di chuyển chuỗi sang thanh ghi cho đối số thứ hai, đặt thanh ghi đầu tiên thành 2 và đặt thanh ghi thứ ba thành vùng màu đỏ (128 byte bên dưới con trỏ ngăn xếp) vì tôi không quan tâm đến kết quả. Sau đó, tôi có thể chỉ đơn giản là jmpđể inet_ptonvà để điều đó trở lại thẳng đến người gọi!

Tôi quay chương trình kiểm tra nhanh này để kiểm tra trường hợp của bạn:

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

Lắp ráp nasm -felf64 assembly.asm, biên dịch với gcc -no-pie test.c assembly.ovà bạn sẽ nhận được:

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

Tôi có thể làm cho nó nhỏ hơn nhiều nếu người gọi được cho là vượt qua AF_INEThoặc AF_INET6đến chức năng


4
Tôi thích rằng bạn đã làm điều này trong asm. Và thực tế bạn đã giải thích nó cho những người có thể không hiểu nó (cũng như mã kiểm tra) thậm chí còn tốt hơn. Điều đó không có nghĩa là tôi có thể thực hiện nó trong asm; Đã quá nhiều năm trôi qua nhưng tôi nhớ đủ để thấy chính xác lời giải thích của bạn (và do đó là quá trình) đang nói (không). Làm tốt lắm.
Pryftan

4
e9 00 00 00 00là a jmp near $+5, không phải a jmp inet_pton. Nếu bạn cung cấp opcode, bạn nên bao gồm inet_ptonphần bao gồm , không để trống
l4m2


3
bạn nên bao gồm extern trong tiêu đề câu trả lời, vì chương trình yêu cầu nó và nó không có sẵn trên tất cả các nền tảng.
qwr

1
"Mov rdi, 2" có thể là "đẩy 2 / pop rdi" cho -2 byte. Cũng lưu ý rằng việc tháo gỡ là sai hoặc mã sai. Đó là "Mov edi" (không phải rdi) hoặc thiếu tiền tố.
perr ferrie

13

Java (JDK) , 63 byte

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

Hãy thử trực tuyến!

Tín dụng

  • -1 byte nhờ Kevin Cruijssen
  • l4m2 để hiển thị các trường hợp thất bại trước đó .1.1.1.1.

Bạn đã quên loại bỏ dấu chấm phẩy. ;) Và tôi có thể xác minh nó hoạt động cho tất cả các trường hợp thử nghiệm, bao gồm cả những trường hợp trong các bình luận. Sẽ thấy nếu tôi thấy một số điều để chơi golf.
Kevin Cruijssen

3
Thất bại vào.1.2.3.4
l4m2

Có được phép sử dụng boolean khi yêu cầu 0/1 không?
l4m2

1
@ l4m2 Câu hỏi ban đầu có Hợp lệ / Không hợp lệ. Vì vậy, tôi cho rằng bất kỳ giá trị trung thực / falsey đều được chấp nhận ở đây.
Kevin Cruijssen

Output: 0 or 1và Java không có
bool auto-

12

JavaScript (Node.js) , 43 byte

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

Hãy thử trực tuyến!

JavaScript (Node.js) , 46 byte

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

Hãy thử trực tuyến!

đã sử dụng một phần của Arnauld

JavaScript (Node.js) , 54 53 51 byte

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

Hãy thử trực tuyến!

-2B cho 0+t<256, -1B từ Patrick Stephansen, + 1B để tránh đầu vào1.1.1.1e-80

Giải pháp RegExp 58 54 byte

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

Cảm ơn Deadcode vì 3 byte


Tôi đã thêm một số trường hợp thử nghiệm!
rv7

Điều này mang lại sự thật cho 0.0.0.0. Mọi thứ khác dường như hoạt động tốt.
Kevin Cruijssen

1
@KevinCruijssen 0.0.0.0là đây đúng. Tại sao SQL tiêm lại ở đây?
l4m2

Đợi đã, tôi hiểu sai câu trong phần mô tả thử thách. 0.0.0.0thực sự là sự thật Đó là ý chí golf câu trả lời của tôi cũng .. (? Và điều gì làm bạn có ý nghĩa bởi SQL injection: S Liên kết là để TIO với trường hợp kiểm tra tất cả.)
Kevin Cruijssen

1
@ l4m2 Tôi đã thêm nó vì chúng tôi cần một số testcase thậm chí trông không giống địa chỉ IP.
tsh

11

PHP , 39 36 byte

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

Hãy thử trực tuyến!

275 giống như hằng số FILTER_VALIDATE_IP

5 ** 9 đang được sử dụng thay vì hằng số FILTER_FLAG_IPV4. Điều này là đủ, bởi vì sự 5**9 & FILTER_FLAG_IPV4thật, đó chính xác là những gì PHP làm trong nền, như Benoit Esnard đã chỉ ra.

Ở đây, filter_vartrả về đối số đầu tiên, nếu đó là địa chỉ IPv4 hợp lệ hoặc sai nếu không phải là địa chỉ. Với +!!, chúng tôi sản xuất đầu ra theo yêu cầu của thách thức.


3
Sử dụng 5**9thay vì 1048576tiết kiệm 3 byte ở đây: PHP sử dụng &để kiểm tra các cờ IPv4 / IPv6 , do đó, bất kỳ số nào trong khoảng từ 1048576 đến 2097151 đều hợp lệ.
Benoit Esnard

Tôi xin từ chối câu trả lời của bạn vì (về cơ bản) câu trả lời của tôi: codegolf.stackexchange.com/a/174470/14732 được viết vào 2018-10-22 09: 17: 34UTC trong khi của bạn được viết vào 2018-10-22 09: 21: 55UTC. Ngay cả khi tôi hoàn nguyên tối ưu hóa 1 byte được cung cấp bởi @BenoitEsnard, câu trả lời của tôi hoàn toàn giống với chức năng của bạn.
Ismael Miguel

2
Tôi phải xin lỗi, tôi đã không thấy câu trả lời của bạn, mặc dù tại thời điểm tôi đang soạn nó, không có bài viết nào về PHP về câu hỏi này (như bạn đã nói, sự khác biệt về thời gian là ít hơn năm phút).
oktupol

Tôi biết, và tôi hiểu nó. Tôi chỉ nhận thấy bạn bây giờ. Tôi có thể khôi phục lại của tôi, và bạn giữ tối ưu hóa. Nhưng tôi không biết liệu nó có làm cho câu trả lời đủ khác biệt với nhau không.
Ismael Miguel

17
@IsmaelMiguel Tôi sẽ không đánh giá thấp ai đó vì nếu điều đó hợp lý thì bạn đã không ở đó khi họ bắt đầu. Với chênh lệch 5 phút, không chỉ có lý, mà gần như chắc chắn là như vậy, điều này rõ ràng ngay cả khi chính tác giả không nói như vậy.
Duncan X Simpson

11

PHP, 36 byte

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

ip2longlà một chức năng tích hợp nổi tiếng .



Điều này dường như sử dụng các tính năng chưa được trình bày trong các phiên bản mới hơn (tôi đoán nó là từ PHP7 +). Hãy nhớ rằng, đối với PHP 4 và 5, điều này không chấp nhận IP không hoàn chỉnh.
Ismael Miguel



1
Điều này sẽ mang lại thành công nếu bạn cung cấp cho nó bất kỳ số nguyên nào, chẳng hạn như 1, 2, v.v. Đừng nghĩ rằng nó nên như vậy. Và nếu bạn cho nó ăn thứ gì đó là 100.100.100
nl-x

10

Perl 6 , 22 21 20 byte

-1 byte nhờ Phil H.

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

Hãy thử trực tuyến!

Giải trình

{                  }  # 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
Man, tôi cần dành nhiều thời gian hơn để tìm ra các biểu thức của Perl 6. Tôi không có %sửa đổi tồn tại. Tôi tự hỏi nếu nó cố gắng kiểm tra tất cả các 256**4khả năng?
Jo King

1
Thay vì <{^256}>bạn chỉ có thể chuyển đổi phạm vi thành một mảng @(^256)cho -1 char TIO . Bằng cách thay đổi khối mã thành một mảng, nó cũng sẽ nhanh hơn rất nhiều (0,4 thay vì> 30).
Phil H

@PhilH Tuyệt, cảm ơn. Tôi đã thử $(^256)nhưng bây giờ tôi nhận ra tại sao điều này không hiệu quả.
nwellnhof

9

05AB1E , 26 24 23 22 23 byte

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

-1 byte nhờ @Emigna .
+1 byte cho trường hợp kiểm tra sửa 1.1.1.1E1lỗi không chính xác trả về kết quả trung thực.

Hãy thử trực tuyến hoặc xác minh tất cả các trường hợp thử nghiệm .

Giải trình:

'.¡              '# 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
Bạn sẽ có thể sử dụng Āthay vì<d
Emigna

@MagicOctopusUrn Tôi sợ nó không cho 1.1.1.1E1, 1..1.1.1, 1.1.1.1., 192.00.0.255, và 0.00.10.255. (PS: Tôi đã sửa 1.1.1.1E1lỗi bằng cách thêm vào þkiểm tra tham gia và bình đẳng.)
Kevin Cruijssen

Đủ công bằng, hình dung tôi đã bỏ lỡ một cái gì đó.
Bạch tuộc ma thuật Urn

@MagicOctopusUrn Vấn đề chính là 05AB1E thấy các số có số 0 đứng đầu bằng với số không có, thậm chí là chuỗi. Đó là lý do tại sao tôi sử dụng DïþJsJQkiểm tra nơi ïđúc nó vào int để loại bỏ 0s hàng đầu, và þchỉ lá chữ số cách loại bỏ những thứ như E, -vv :) Các là đối với trường hợp kiểm tra 0.00.10.255, kể từ 000102550010255sẽ được bình đẳng.
Kevin Cruijssen

Vâng, tôi đã trải qua những điều vô nghĩa tương tự, sự đảo ngược của tất cả các con số hoạt động khá tốt, ngoại trừ những trường hợp đó. Thật thú vị khi các tính năng có lợi cho một số vấn đề trở nên gần giống như lỗi đối với những người khác.
Bạch tuộc ma thuật Urn

6

PowerShell, 59 51 49 byte

-8 byte, cảm ơn @AdmBorkBork

-2 byte truehoặc falseđược tác giả cho phép

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

Kịch bản thử nghiệm:

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

Đầu ra:

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

Giải trình:

Kịch bản lệnh cố phân tích một chuỗi đối số, để xây dựng một đối tượng .NET, IPAddress .

  • return $truenếu objectđược tạo và chuỗi đối số bằng với một chuỗi đại diện của object(địa chỉ được chuẩn hóa bởi object.toString())
  • trở lại $falsebằng cách khác

PowerShell, 59 56 54 byte, 'không sử dụng thay thế .NET lib'

-3 byte truehoặc falseđược tác giả cho phép

-2 byte, nhờ @ Deadcode cho regrec tuyệt vời.

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

Hãy thử trực tuyến!

Cảm ơn @ Olivier Grégoire cho biểu thức chính quy ban đầu.


1
Bạn không cần phải gọi |% t*gvì PowerShell sẽ tự động chuyển phía bên phải -eqthành một chuỗi, vì phía bên trái là một chuỗi. -try{+("$args"-eq[IPAddress]::Parse($args))}catch{0}
admBorkBork

Bạn có thể khắc 2 byte từ phiên bản "không sử dụng .NET lib" bằng cách sử dụng regex của tôi (được điều chỉnh theo thủ thuật chèn thời gian, tất nhiên không thể có trong phiên bản của tôi vì đó là regex thuần túy): tio.run/ Kẻ
Deadcode

5

C (gcc) / POSIX, 26 byte

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

Hãy thử trực tuyến!

Hoạt động như mã 64 bit trên TIO nhưng có lẽ yêu cầu điều đó sizeof(int) == sizeof(char*)trên các nền tảng khác.


@TobySpeight Có, nếu bạn ở trên x86, có lẽ bạn nên thử ở chế độ 32 bit ( -m32).
nwellnhof

Tôi đã làm cho nó hoạt động, bằng cách chuyển qua snhư một char*(không có quyền truy cập vào hệ thống ILP32 ở đây), và vâng, tôi đã trộn lẫn với inet_aton().
Toby Speight

5

PHP 7+, 37 35 32 byte

Điều này sử dụng hàm dựng sẵn filter_var, để xác thực rằng đó là một địa chỉ IPv4 .

Để nó hoạt động, bạn cần chuyển khóa iqua yêu cầu GET.

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

Sẽ không có gì (cho falsykết quả) hoặc IP (cho truthykết quả), tùy thuộc vào kết quả.

Bạn có thể thử điều này trên: http://sandbox.onlinephpfifts.com/code/639c22281ea3ba753cf7431281486d8e6e66f68e http://sandbox.onlinephpfifts.com/code/ff6aaeb2b2d0e0ac43f48125de0549320bc071b4


Điều này sử dụng trực tiếp các giá trị sau:

  • 275 = FILTER_VALIDATE_IP
  • 1 << 20 = 1048576 = FILTER_FLAG_IPV4
  • 5 ** 9 = 1953125 (có bit yêu cầu là "1", cho 1048576)

Cảm ơn Benoit Esnard vì mẹo này đã giúp tôi tiết kiệm 1 byte!

Cảm ơn Titus đã nhắc nhở tôi về những thay đổi của thử thách.


Tôi đã xem xét việc sử dụng chức năng ip2long, nhưng nó hoạt động với các địa chỉ IP không đầy đủ.

Địa chỉ IPv4 không đầy đủ được coi là không hợp lệ trong thử thách này.

Nếu chúng được cho phép, đây sẽ là mã cuối cùng (chỉ dành cho PHP 5.2.10):

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

Hiện tại, tài liệu này không rõ ràng rằng điều này sẽ ngừng hoạt động (khi đã chuyển một ip không hoàn chỉnh) với các phiên bản PHP mới hơn.

Sau khi thử nghiệm, xác nhận rằng đó là trường hợp.

Cảm ơn nwellnhof cho tiền boa!


Sử dụng 5**9thay vì 1<<20lưu một byte ở đây: PHP sử dụng &để kiểm tra các cờ IPv4 / IPv6 , do đó, bất kỳ số nào trong khoảng từ 1048576 đến 2097151 đều hợp lệ.
Benoit Esnard

Trong các phiên bản PHP mới hơn, ip2longkhông cho phép các địa chỉ không đầy đủ.
nwellnhof

@BenoitEsnard Cảm ơn bạn! Tôi đã thêm nó vào câu trả lời
Ismael Miguel

@nwellnhof Sau khi thử nghiệm, tôi xác nhận rằng đó là trường hợp. Tuy nhiên, tôi không nghĩ nên sử dụng nó vì nó không được ghi chép rõ ràng.
Ismael Miguel

+!!không được yêu cầu; OP hiện chấp nhận các giá trị trung thực tùy ý.
Tít

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

Lặp lại tất cả các địa chỉ IPv4 có thể, lấy biểu diễn chuỗi và so sánh nó với đầu vào. Nó ... phải mất một lúc để chạy.

EDIT: Đã xóa 3 byte bằng cách chuyển từ chương trình đầy đủ sang chức năng ẩn danh.

EDIT2: Đã xóa 8 byte với sự trợ giúp từ xnor

EDIT3: Đã xóa 1 byte bằng cách sử dụng bản đồ được giải nén thay vì hiểu danh sách

EDIT4: Đã xóa 3 byte bằng cách sử dụng hiểu danh sách thay vì ipaddressmô-đun


2
Tôi nghĩ rằng chức năng ẩn danh của bạn chỉ có thể được [str(ip_address(x))for x in range(256**4)].count. Ngoài ra, 256**4có thể được 16**8.
xnor

5

C # (Trình biên dịch tương tác Visual C #) , 84 79 65 byte

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

Hãy thử trực tuyến!

-5 và -14 byte được lưu nhờ @dana!

# C # (Trình biên dịch tương tác Visual C #) , 61 byte

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

Hãy thử trực tuyến!

Công việc này đang được tiến hành. Mã sử ​​dụng System.Net(+17 byte nếu bạn đếm nó). nếu bạn tự hỏi tại sao tôi đếm và phân tích:

Hạn chế với phương thức IPAddress.TryPude là nó xác minh xem một chuỗi có thể được chuyển đổi thành địa chỉ IP hay không, do đó, nếu nó được cung cấp với giá trị chuỗi như "5", thì nó coi đó là "0.0.0.5".

nguồn

Như @milk đã nói trong bình luận, nó thực sự sẽ thất bại trên các số 0 hàng đầu. Vì vậy, 61 byte một không hoạt động.


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().

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.