Tantangan
Diberi IPv4 address
dalam notasi quad-dotted, dan IPv4 subnet
pada notasi CIDR , tentukan apakah IPv4 address
berada di dalam subnet
. Keluarkan nilai yang berbeda dan konsisten jika berada dalam subnet
, dan nilai yang berbeda dan konsisten terpisah jika tidak ada dalam subnet
. Nilai-nilai output tidak harus benar-benar benar / salah dalam bahasa Anda.
CIDR subnet notasi primer singkat
Alamat jaringan IPv4 panjangnya 32 bit, dibagi menjadi empat kelompok 8 bit untuk kemudahan membaca. Notasi subnet CIDR adalah topeng dari jumlah bit yang ditentukan, mulai paling kiri. Misalnya, untuk sebuah /24
subnet, ini berarti 8 bit alamat yang paling tepat tersedia di subnet itu. Jadi dua alamat yang dipisahkan oleh paling banyak 255
, dan memiliki subnet mask yang sama, berada di subnet yang sama. Perhatikan bahwa CIDR yang valid memiliki semua bit host (sisi kanan) tidak disetel (nol).
xxxxxxxx xxxxxxxx xxxxxxxx 00000000
^--- subnet mask ---^ ^-hosts-^
Untuk contoh lain, sebuah /32
subnet menentukan bahwa semua bit adalah subnet mask, yang pada dasarnya berarti bahwa hanya satu host yang diizinkan per /32
.
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
^--- subnet mask ---^
Contoh:
Menggunakan True
untuk "di subnet" dan False
untuk "tidak di subnet" sebagai output:
127.0.0.1
127.0.0.0/24
True
127.0.0.55
127.0.0.0/23
True
127.0.1.55
127.0.0.0/23
True
10.4.1.33
10.4.0.0/16
True
255.255.255.255
0.0.0.0/0
True
127.1.2.3
127.0.0.0/24
False
127.1.2.3
127.1.2.1/32
False
10.10.83.255
10.10.84.0/22
False
Aturan dan Klarifikasi
- Karena parsing input bukan poin menarik dari tantangan ini, Anda dijamin untuk mendapatkan alamat IPv4 dan subnet mask yang valid.
- Input dan output dapat diberikan dengan metode apa pun yang mudah .
- Anda dapat mencetak hasilnya ke STDOUT atau mengembalikannya sebagai hasil fungsi. Silakan sebutkan dalam kiriman Anda nilai apa yang bisa diambil oleh output.
- Program lengkap atau fungsi dapat diterima.
- Celah standar dilarang.
- Ini adalah kode-golf sehingga semua aturan golf biasa berlaku, dan kode terpendek (dalam byte) menang.
sumber
10.0.0.1/10.0.0.0”/16
?1.255.1.1/8
adalah ekspresi CIDR yang valid , mewakili host1.255.1.1
dalam jaringan1.0.0.0
dengan subnet mask dari255.0.0.0
. Namun tantangannya meminta nomor jaringan dan subnet khusus dalam notasi CIDR, yang1.255.1.1/8
bukan nomor jaringan dan kombinasi subnet yang valid.Jawaban:
Python 3 (62 byte)
Sangat mudah:
sumber
ip_adress
objek danip_network
objek merupakanany convenient method
, mungkin membiarkan Python menang, kecuali jika bahasa golf berbasis python menjadikannya sebagai tipenya?(host^net)>>(32-mask)
hanya 10 byte. Tapi itu setengah jalan di antara untuk tugas-tugas yang tidak melibatkan daftar daftar, atau memetakan fungsi ke daftar, karena banyak operasi skalar dapat dilakukan dengan instruksi 2 atau 3 byte, dan loop dapat dibangun di sekitar hal-hal dalam beberapa byte.C # (Visual C # Compiler) , 250 + 31 = 281 byte
Bytecount termasuk
using System;using System.Linq;
Cobalah online!
Saya menulis ini di JS segera setelah tantangan diposting, tetapi Arnauld mengalahkan saya sampai tepat dengan jawaban yang jauh lebih baik, jadi ini dia dalam C #.
Pasti banyak ruang untuk bermain golf.
Penjelasan:
Fungsi terdiri dari sub-fungsi yang disebut
h
:Subfungsi ini membagi Alamat IP aktif
.
, mengubah setiap nomor menjadi string biner, dengan bantalan kiri masing-masing string0
menjadi 8 bit, kemudian menggabungkan string menjadi satu string biner 32-bit.Ini segera dilakukan di tempat dengan
a=h(a);
pada Alamat IP yang diberikan.Kami kemudian membagi Subnet mask menjadi Alamat IP dan nomor mask dengan
c=b.Split('/');
Komponen Alamat IP juga dilewatkan melalui sub-fungsi kami:
b=h(c[0]);
dan nomor mask diurai ke integer:var d=int.Parse(c[1]);
Akhirnya kita mengambil
d
bit pertama dari kedua string biner (di manad
nomor mask) dan membandingkannya:return a.Substring(0,d)==b.Substring(0,d);
sumber
rPad
memiliki string bawaan. tautan pastebin ke tautan TIO yang terlalu panjangLinux POSIX shell (dengan net-tools / iputils) (34 byte non-terminating, 47 byte terminating)
Apa yang paling cocok untuk mengurai topeng dan alamat jaringan daripada utilitas jaringan itu sendiri? :)
Peringatan: skrip berpotensi merusak konektivitas Internet Anda, harap jalankan dengan hati-hati.
Input: skrip mengambil alamat IP yang diuji sebagai argumen pertama, dan subnet yang diuji. sebagai argumen kedua.
Keluaran: skrip mengembalikan nilai kebenaran (0) jika argumen pertama skrip milik subnet yang ditunjukkan dalam argumen kedua. Kalau tidak, itu tidak akan pernah berakhir.
Asumsi: skrip harus dijalankan sebagai pengguna root, di lingkungan yang bersih ( yaitu , tidak ada rute lubang hitam lain yang telah ditetapkan oleh administrator, dan jika instance skrip sebelumnya telah dijalankan, rute lubang hitam yang dibuatnya telah dihapus ). Skrip juga mengasumsikan "koneksi Internet yang berfungsi" ( yaitu , rute default yang valid ada).
Penjelasan:
Kami membuat rute blackhole ke subnet yang ditentukan. Kami kemudian menguji konektivitas ke alamat IP yang disediakan dengan menggunakan ping . Jika alamat tersebut bukan milik subnet (dan karena kami menganggap koneksi Internet diatur dengan benar), ping akan mencoba mengirim paket ke alamat itu. Perhatikan bahwa apakah alamat ini benar-benar merespons tidak masalah, karena ping akan terus mencoba selamanya. Sebaliknya, jika alamat itu milik subnet, ping akan gagal dengan ENETUNREACH dan mengembalikan 2, dan karena kita meniadakan perintah, skrip akan berhasil.
Contoh
Uji apakah 5.5.5.5 milik 8.8.8.0/24
(Bersihkan dengan
sudo ip route del 8.8.8.0/24
setelah menjalankan perintah).Uji apakah 5.5.5.5 milik 5.5.5.0/24:
(Bersihkan dengan
sudo ip route del 5.5.5.0/24
setelah menjalankan perintah).Uji apakah 8.8.8.8 milik 5.5.5.0/24:
(Bersihkan dengan
sudo ip route del 5.5.5.0/24
setelah menjalankan perintah).Versi 47 byte jika kita melarang skrip yang tidak berhenti
Sesuai komentar @ Grimy, inilah versi yang selalu berakhir, dan mengembalikan 0 (benar) jika alamatnya ada di subnet, dan 1 (salah) sebaliknya. Kami membuat ping berakhir dengan
-c1
bendera yang membatasi jumlah paket yang dikirim ke 1. Jika alamat merespons, ping akan mengembalikan 0, dan jika tidak, ping akan kembali 1. Hanya jika alamat milik subnet yang dihitamkan akan melakukan ping kembali 2, yang dengan demikian kita uji terhadap pada perintah terakhir.sumber
ping
akan mati dari SIGPIPE jika dijalankan dengan stdout + stderr disalurkan ke program lain, dan pembaca menutup pipa. Dan itu adalah kasus penggunaan yang paling mungkin karena status keluar dapat berhasil dengan cara apa pun (jika kami menambahkan-c1
opsi untuk melakukan ping untuk mengatur penghitungan.) Tetapi tentu saja, membaca hasilnya denganvar=$(/a.sh)
akan gagal; Anda akan membutuhkan pembaca yang berhenti setelah memutuskan, daripada membaca seluruh output dan kemudian melihatnya.ping
akan berakhir dalam waktu kurang dari, katakanlah, satu detik dalam kasus alamat yang dihitamkan). Saya menambahkan versi terminating untuk tambahan 13 byte! :)JavaScript (ES6), 82 byte
Mengambil input sebagai
(address)(subnet)
. Mengembalikan nilai Boolean.Cobalah online!
sumber
PHP ,
1019288 byte-13 byte dari @gwaugh
Cobalah online!
sumber
function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
strtok()
. Milik Anda 4 byte lebih pendek dari jawaban saya yang sangat mirip di bawah ini. Atribut!PowerPC / PPC64 C,
116114 byte(Diuji pada x86_64 Ubuntu 18.04 menggunakan powerpc64-linux-gnu-gcc -static dan qemu-user.)
Program mengambil dua baris pada input standar, dan sebagai kode keluarnya mengembalikan 1 jika alamat cocok dan 0 jika tidak. (Jadi ini tergantung pada spesifikasi yang tidak membutuhkan nilai kebenaran untuk pertandingan dan nilai kesalahan untuk ketidakcocokan.) Perhatikan bahwa jika Anda menjalankan secara interaktif, Anda perlu memberi sinyal EOF (
^D
) tiga kali setelah memasukkan baris kedua.Ini bergantung pada PowerPC sebagai big-endian, dan juga pada platform yang mengembalikan 0 untuk menggeser nilai 32-bit yang tidak ditandatangani oleh 32. Ia membaca oktet menjadi nilai yang tidak ditandai satu-per-satu, bersama dengan panjang netmask pada byte lain ; kemudian mengambil xor dari dua alamat 32-bit yang tidak ditandatangani dan menggeser bit yang tidak relevan. Akhirnya, itu berlaku
!
untuk memenuhi persyaratan mengembalikan hanya dua nilai yang berbeda.Catatan: mungkin mungkin untuk mencukur dua byte dengan mengganti
u+3
denganp
dan membutuhkan kompilasi dengan-O0
. Tapi itu hidup lebih berbahaya daripada yang aku pedulikan.Terima kasih kepada Peter Cordes untuk inspirasi untuk solusi ini.
Lebih portabel C,
186171167 byteDi sini saya akan mempertahankan versi yang lebih portabel yang berjalan 167 byte.
Program ini mengambil dua baris pada input standar, dan mengembalikan kode keluar 1 jika alamatnya ada di subnet, dan 0 jika tidak. (Jadi ini bergantung pada spesifikasi yang tidak membutuhkan nilai kebenaran untuk pertandingan dan nilai palsu untuk tidak cocok.)
Rincian ekspresi inti:
a^e
,b^f
,c^g
,d^h
Menghitung XOR dari alamat dan topeng byte-by-byte.(((a^e)<<8|b^f)<<8|c^g)<<8|d^h
kemudian menggabungkan mereka ke dalam nilai 32-bit unsigned tunggal dengan metode seperti Horner....>>32-n
kemudian menggeser bit dari perbedaan xor yang tidak relevan dengan subnet mask (mengingat bahwa-
memiliki prioritas lebih tinggi dalam C daripada<<
)~0U<<32
akan memberikan perilaku yang tidak terdefinisi dengan asumsiunsigned
32 bit (yang ada di hampir semua platform saat ini). Di sisi lain, jika n = 0 maka alamat mana pun akan cocok, sehinggan&&...
akan memberikan hasil yang benar (memanfaatkan perilaku hubungan arus pendek&&
).!
untuk output 0 atau 1.-15 byte karena komentar oleh ceilingcat dan AdmBorkBork
-4 byte karena komentar dari Peter Cordes
sumber
unsigned
. misalnya denganchar*p=&a
kemudianp++,p++,p++,...
ataup--,...
sebagai scanf args. Namun, format string perlu"%hhu.%hhu..."
, jadi itu adalah tradeoff yang signifikan antara ukuran ekstra vs mendeklarasikan lebih sedikit vars dan mampu melakukannya(a^b)>>(32-count)
Stax , 22 byte
Jalankan dan debug itu
Dibutuhkan parameter input yang dipisahkan oleh ruang pada input standar.
Dibongkar, tidak diserang, dan dikomentari, sepertinya ini.
Jalankan yang ini
sumber
fungsi kode mesin x86-64,
5348 bytechangelog:
jz
alih-alih shift alih-alih menggunakan shift 64-bit untuk menangani>>(32-0)
case khusus.setnz al
.(Lihat juga jawaban kode mesin 32-bit Daniel Schepler berdasarkan ini, yang kemudian berevolusi untuk menggunakan beberapa ide lain yang kami miliki. Saya menyertakan versi terbaru saya tentang itu di bagian bawah jawaban ini.)
Mengembalikan ZF = 0 untuk host tidak di subnet, ZF = 1 untuk di subnet, sehingga Anda dapat bercabang pada hasilnya dengan
je host_matches_subnet
Callable dengan konvensi pemanggilan System V x86-64 seolah-
bool not_in_subnet(int dummy_rdi, const char *input_rsi);
olah Anda menambahkansetnz al
.String input berisi host dan jaringan, dipisahkan dengan tepat 1 karakter non-digit. Memori yang mengikuti ujung lebar CIDR harus mengandung setidaknya 3 byte non-digit sebelum akhir halaman. (Seharusnya tidak menjadi masalah dalam kebanyakan kasus, seperti untuk argumen cmdline.) Versi 32-bit Daniel tidak memiliki batasan ini.
Kami menjalankan loop parse bertitik-quad yang sama 3 kali, mendapatkan dua alamat IPv4, dan mendapatkan
/mask
sebagai integer dalam byte tinggi kata. (Inilah sebabnya mengapa harus ada memori yang dapat dibaca setelah/mask
, tetapi tidak masalah jika ada angka ASCII.)Kami lakukan
(host ^ subnet) >> (32-mask)
untuk menggeser bit host (yang diizinkan untuk tidak cocok), hanya menyisakan perbedaan antara subnet dan host. Untuk menyelesaikan/0
kasus khusus di mana kita perlu menggeser sebesar 32, kita melompati shift dengan hitungan = 0. (neg cl
set ZF, yang bisa kita percabang dan tinggalkan sebagai nilai balik jika kita tidak menggeser.) Perhatikan itu32-mask mod 32 = -mask
, dan x86 pergeseran skalar menyamarkan jumlah mereka dengan& 31
atau& 63
.(tidak diperbarui dengan versi terbaru) Cobalah secara online!
termasuk a
_start
yang memanggilnyaargv[1]
dan mengembalikan status keluar.Ini berfungsi dengan baik jika Anda melewati argumen baris perintah yang berisi baris baru dan bukan spasi. Tetapi harus sebaliknya , tidak juga.
fungsi kode mesin x86 32-bit, 38 byte
Do 9 integer -> uint8_t mem-parsing dan "mendorong" mereka di stack, di mana kita mematikannya sebagai kata-kata atau menggunakan yang terakhir masih di CL. Hindari membaca melewati ujung string sama sekali.
Juga,
dec
hanya 1 byte dalam mode 32-bit.Penelepon uji
sumber
cmp/jcc
yang Anda sebutkan Anda melakukan sesuatu sepertixor edx,edx;neg cl;cmovz eax,edx;shr eax,cl
- atau mungkin Anda sudah memiliki nilai 0 nongkrong di suatu tempat. (Dan kemudian Anda tidak akan memerlukansub cl,32
instruksi.)edi
harus 0 ketika loop keluar, jadixor eax,edx;neg cl;cmovz eax,edi;shr eax,cl
harus bekerja.cmove eax,edi
memiliki 3 byte yang merupakan wash over yang dihapussub cl,32
kemudianshr cl,eax
menyimpan satu byte lebihshr cl,rax
dan 32-bitdec edi
menyimpan satu byte lebih dari 64-bitdec edi
. Majelis saya kemudian memberikan.byte 0x33
(dalam sintaks GNU binutils) = 51 untukin_subnet.size
.shr eax,cl
, vs.shr %cl, %eax
dalam sintaks AT&T, komentar terakhir Anda membalikkan itu.) Agak sulit untuk memperbarui jawaban kode mesin (dan port_start
pemanggil dan uraikan kembali konvensi pemanggilan untuk mode 32-bit .. .), jadi saya mungkin tidak bisa melakukannya. Merasa malas hari ini. >. <edi
tulis, tulis output, dll. Akhirnya menghemat 2 byte dalam jaring (Paling tidak satu kali saya sadaripush ecx;push ecx;push ecx
lebih pendek darisub esp,12
; dan itu sepertinya merupakan pembasuhan apakah saya telah ditetapkan sebelumnyaedi
dan digunakanstd;stosb;cld
atau apakah saya baru saja disimpan menggunakandec edi;mov [edi],al
.Jelly , 23 byte
Cobalah online!
Tautan monadik yang mengambil alamat dan subnet dipisahkan oleh garis miring dan mengembalikan 1 untuk true dan 0 untuk false.
Terima kasih kepada @gwaugh karena menunjukkan kekurangan pada aslinya - gagal memastikan daftar binernya 32 panjang.
sumber
Perl 5
-Mbigint -MSocket=:all -p
, 72 byteCobalah online!
sumber
05AB1E , 21 byte
Mengambil subnet sebelum alamat.
Cobalah secara online atau verifikasi semua kasus uji .
Penjelasan:
sumber
R 120 byte
fungsi - saya tempelkan ".32" ke istilah pertama
w=function(a,b){f=function(x)as.double(el(strsplit(x,"[./]")));t=f(paste0(a,".32"))-f(b);sum(t[-5]*c(256^(3:0)))<2^t[5]}
dan hanya untuk bersenang-senang:
require("iptools");w=function(a,b)ips_in_cidrs(a,b)[[2]]
yaitu 56 byte
sumber
PHP ,
7573, 71 byteSebuah fork jawaban @Luis felipe De jesus Munoz , sebagai mandiri mengambil input dari argumen baris perintah. Output
'1'
untuk Truthy,''
(string kosong) untuk Fasley.Cobalah online!
-2 byte meminjam sedikit trik untuk Christoph
strtok()
. Jawabannya masih lebih pendek!sumber
fungsi perakitan x86,
4943 byteIni sebagian besar diposting untuk memenuhi permintaan Peter Cordes untuk versi revisi yang saya buat. Mungkin bisa hilang sekali / jika dia memasukkannya ke dalam jawabannya.
Fungsi ini berharap
esi
untuk menunjuk ke string input, dengan bagian alamat dan subnet dipisahkan baik oleh spasi atau karakter baris baru, dan nilai kembali berada di bendera ZF (yang menurut definisi hanya memiliki dua nilai yang mungkin).Dan bagian pembungkus x86 Linux:
-6 byte karena saran dari Peter Cordes untuk mengembalikan nilai dalam ZF.
sumber
xor edx,edx
dan mengganticmovz eax,edx
denganjz .nonzero; xor eax,eax; .nonzero:
.cmovz
masih menang jika kita memiliki konvensi panggilanebx=0
.jz
atasshr
ke Setz atau ret itu? Kami dapat menukarsetnz
kesetz
dan kembali1
untuk pertandingan jika itu membantu. Atau bahkan mengatakan bahwa nilai pengembalian kami adalah ZF. Seharusnya saya melakukan itu dalam jawaban saya. (Tapi saya tidak berpikir kita dapat membenarkan mengharuskan penelepon membuat konstanta untuk kita, sepertiebx=0
. Jawaban saya pada Tips untuk bermain golf dalam kode mesin x86 / x64 berargumen bahwa terlalu jauh akan memperpanjang konvensi panggilan kustom.cut
untuk menghapus beberapa kolom dari NASM daftar output karena semua instruksi saya singkat:nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Juga, saya menggunakan mov daripada movzx di_start
pemanggil saya karena status keluar berasal dari byte rendah dari arg kesys_exit()
. Kernel mengabaikan byte yang lebih tinggi.setnz al
setelahcall in_subnet
dalam bungkus.call
/je
, daripada mencetak atau meneruskan hasilnya. Seperti yang saya tunjukkan dalam "tips", beberapa konvensi pemanggilan sistem sudah melakukan ini dalam kehidupan nyata (biasanya dengan CF = kesalahan).Java
215 211 207 202 200 199 198 190180 byteKeluaran
true
untuk kebenaran danfalse
kepalsuan.Catatan: Ini menggunakan
long
alih-alihint
untuk potensi pergeseran kanan 32.Cobalah online!
Disimpan 1 byte berkat ceilingcat
Disimpan 10 byte berkat Peter Cordes
sumber
host ^ net
untuk menggeser bit yang ingin Anda hapus, alih-alih benar-benar membuat topeng. Tapi saya kira Java perlu membandingkan di sana untuk membuat boolean dari integer. Mungkin!
, karena tidak masalah mana yang benar atau salah yang Anda hasilkan untuk output mana. (Saya meminta OP untuk klarifikasi tentang apakah mereka bermaksud mengecualikan 0 / non-nol, dan mereka menjawab ya mereka sadar akan konsekuensi dari kata-kata itu:long
tidak kehilangan saya beberapa byte tapi saya menebusnya dengan bisa menghapus ternary dan melakukan XOR seperti yang Anda sarankan. Saya sedang memeriksa apa lagi yang bisa saya mainkan sebelum mempostingArang , 36 byte
Cobalah online! Tautan adalah untuk mengucapkan versi kode. Mengambil subnet sebagai parameter pertama dan dan output
-
hanya jika alamatnya berada di dalam subnet. Penjelasan:Split subnet aktif
/
.Lepaskan topeng dan cor ke integer.
Dorong alamat ke array.
Membagi kedua alamat
.
, mengonversinya menjadi bilangan bulat, mengartikannya sebagai basis 256, dan membuang bit bertopeng.Bandingkan kedua nilai tersebut.
sumber
Japt , 26 byte
Cobalah
-3 byte terima kasih kepada @Shaggy!
Input adalah array dengan 2 elemen
[address, subnet]
. JS yang dialihkan di bawah ini:sumber
++
.g
metode ini mengganggu saya; tidak bisa menemukan jalan keluar sama sekali. Setidaknya tidak satu yang akan menghemat satu byte.C # (Visual C # Interactive Compiler) , 187 byte
Saya pasti bisa menurunkan ini lebih banyak.
Cobalah online!
sumber
C # (Visual C # Interactive Compiler) , 134 byte
Cobalah online!
Pernyataan LINQ yang menggunakan array string 2-elemen sebagai input
[address, subnet]
format.Setiap quad putus-putus dikonversi menjadi 32 bit yang panjang menggunakan manipulasi bit. Bit digeser dengan benar oleh ukuran subnet dan elemen dibandingkan untuk kesetaraan.
Ada beberapa jawaban C # pada saat jawaban ini diposting, tetapi tidak ada yang menggunakan manipulasi bit murni.
sumber
Ruby (48 byte)
sumber
====