Вызов
Учитывая IPv4 address
в нотации с точечным квадратом и IPv4 subnet
в нотации CIDR , определите, есть ли address
в subnet
. Выведите отличительное и непротиворечивое значение, если оно находится в subnet
, и отдельное непротиворечивое и непротиворечивое значение, если его нет в subnet
. Выходные значения не обязательно должны быть правдивыми / ложными на вашем языке.
Краткий учебник по обозначениям подсетей CIDR
Сетевые адреса IPv4 имеют длину 32 бита и разделены на четыре группы по 8 бит для удобства чтения. Обозначение подсети CIDR представляет собой маску с указанным количеством битов, начиная с крайнего левого. Например, для /24
подсети это означает, что в этой подсети доступны самые правые 8 бит адреса. Таким образом, два адреса, которые разделены не более 255
и имеют одинаковую маску подсети, находятся в одной подсети. Обратите внимание, что в действительном CIDR все биты хоста (правая сторона) не установлены (нули).
xxxxxxxx xxxxxxxx xxxxxxxx 00000000
^--- subnet mask ---^ ^-hosts-^
В другом примере /32
подсеть указывает, что все биты являются маской подсети, что означает, что на каждый разрешен только один хост /32
.
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
^--- subnet mask ---^
Примеры:
Использование True
для «в подсети» и False
для «не в подсети» в качестве вывода:
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
Правила и разъяснения
- Поскольку разбор входных данных не является интересной точкой этой проблемы, вы гарантированно получите действительные адреса IPv4 и маски подсети.
- Вход и выход могут быть заданы любым удобным способом .
- Вы можете распечатать результат в STDOUT или вернуть его как результат функции. Пожалуйста, укажите в своем представлении, какие значения могут принимать результаты.
- Либо полная программа или функция приемлемы.
- Стандартные лазейки запрещены.
- Это код-гольф, поэтому применяются все обычные правила игры в гольф, и выигрывает самый короткий код (в байтах).
источник
10.0.0.1/10.0.0.0”/16
?1.255.1.1/8
допустимое выражение CIDR , представляющее хост1.255.1.1
в сети1.0.0.0
с маской подсети255.0.0.0
. Тем не менее, запрос запрашивает номер сети и подсети, в частности, в нотации CIDR, которая1.255.1.1/8
не является допустимой комбинацией номера сети и подсети.Ответы:
Python 3 (62 байта)
Очень просто:
источник
ip_adress
объект иip_network
объектany convenient method
, возможно, позволить Python победить, если только язык игры в гольф на основе Python не имеет их в качестве своих типов?(host^net)>>(32-mask)
только 10 байтов. Но это промежуточная задача для задач, не включающих списки списков или не отображающих функцию в список, потому что многие скалярные операции могут быть выполнены с помощью 2- или 3-байтовой инструкции, а циклы могут быть построены вокруг вещей в несколько байтов.C # (компилятор Visual C #) , 250 + 31 = 281 байт
Bytecount включает в себя
using System;using System.Linq;
Попробуйте онлайн!
Я написал это в JS, как только задание было опубликовано, но Арно обошел меня с ударом с гораздо лучшим ответом, так что вместо этого он находится в C #.
Определенно много места для игры в гольф.
Объяснение:
Функция состоит из подфункции, которая называется
h
:Эта подфункция разделяет IP-адрес
.
, преобразует каждое число в двоичную строку, разбивает слева каждую строку длиной0
до 8 бит, затем объединяет строки в одну 32-разрядную двоичную строку.Это немедленно делается на месте с
a=h(a);
данного IP-адреса.Затем мы разделяем маску подсети на IP-адрес и номер маски с помощью
c=b.Split('/');
Компонент IP-адреса также передается через нашу подфункцию:
b=h(c[0]);
номер маски анализируется в целое число:var d=int.Parse(c[1]);
Наконец, мы берем первые
d
биты обеих двоичных строк (гдеd
находится номер маски) и сравниваем их:return a.Substring(0,d)==b.Substring(0,d);
источник
rPad
встроены в строки. вставьте ссылку на ссылкуОболочка Linux POSIX (с net-tools / iputils) (34 байта не завершаются, 47 байтов заканчиваются)
Что лучше всего подходит для разбора сетевых масок и адресов, чем сами сетевые утилиты? :)
Предупреждение: скрипт может повредить подключение к Интернету, пожалуйста, запустите его с осторожностью.
Входные данные: сценарий принимает в качестве первого аргумента проверенный IP-адрес и проверенную подсеть. в качестве второго аргумента.
Вывод: скрипт возвращает истинное значение (0), если первый аргумент скрипта принадлежит подсети, указанной во втором аргументе. Иначе оно никогда не прекратится.
Допущения: сценарий должен запускаться от имени пользователя root в чистой среде ( т. Е. Администратор не установил другой маршрут черной дыры, и если предыдущий экземпляр сценария был запущен, созданный им маршрут черной дыры был удален ). Сценарий также предполагает «работающее подключение к Интернету» ( т. Е. Присутствует действующий маршрут по умолчанию).
Объяснение:
Мы создаем маршрут черной дыры к указанной подсети. Затем мы проверяем подключение к указанному IP-адресу с помощью ping . Если адрес не принадлежит подсети (и поскольку мы предполагаем, что интернет-соединение установлено правильно), ping попытается отправить пакеты на этот адрес. Обратите внимание, что ответ на этот адрес не имеет значения, поскольку ping будет пытаться работать вечно. И наоборот, если адрес принадлежит подсети, ping завершится неудачно с ENETUNREACH и вернет 2, а поскольку мы отрицаем команду, сценарий будет выполнен успешно.
пример
Проверьте, принадлежит ли 5.5.5.5 к 8.8.8.0/24
(Очистить
sudo ip route del 8.8.8.0/24
после запуска команды).Проверьте, принадлежит ли 5.5.5.5 к 5.5.5.0/24:
(Очистить
sudo ip route del 5.5.5.0/24
после запуска команды).Проверьте, принадлежит ли 8.8.8.8 к 5.5.5.0/24:
(Очистить
sudo ip route del 5.5.5.0/24
после запуска команды).47-байтовая версия, если мы запрещаем не завершающие скрипты
Согласно комментарию @ Grimy, вот версия, которая всегда заканчивается и возвращает 0 (правда), если адрес находится в подсети, и 1 (ложно) в противном случае. Мы заставляем ping завершаться с помощью
-c1
флага, который ограничивает количество отправляемых пакетов до 1. Если адрес ответил, ping вернет 0, а если нет, ping вернет 1. Только если адрес принадлежит подсети с черной дырой, ping вернет 2, это то, что мы проверяем в последней команде.источник
ping
что умрет от SIGPIPE, если он работает с stdout + stderr, переданным в другую программу, и ридер закрыл канал. И это наиболее вероятный вариант использования, потому что состояние выхода может быть успешным в любом случае (если мы добавили-c1
опцию ping для установки счетчика). Но, конечно, чтение его вывода с помощьюvar=$(/a.sh)
завершится неудачей; вам нужен читатель, который остановился после принятия решения, вместо того, чтобы прочитать весь вывод и затем посмотреть на него.ping
в случае адреса с черной дырой будет меньше, чем, скажем, одна секунда). Я добавил завершающую версию для дополнительных 13 байтов! :)JavaScript (ES6), 82 байта
Принимает вход как
(address)(subnet)
. Возвращает логическое значение.Попробуйте онлайн!
источник
PHP ,
1019288 байт-13 байтов от @gwaugh
Попробуйте онлайн!
источник
function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
strtok()
. Ваш на 4 байта короче, чем мой очень похожий ответ ниже. Реквизит!PowerPC / PPC64 C,
116114 байт(Протестировано на x86_64 Ubuntu 18.04 с использованием powerpc64-linux-gnu-gcc -static и qemu-user.)
Программа занимает две строки на стандартном вводе и в качестве кода выхода возвращает 1, если адрес совпадает, и 0, если нет. (Таким образом, это зависит от спецификации, не требующей истинного значения для совпадения и ложного значения для несоответствия.) Обратите внимание, что если вы работаете в интерактивном режиме, вам потребуется
^D
трижды сигнализировать EOF ( ) после входа во вторую строку.Это полагается на то, что PowerPC является байтовым порядком байтов, а также на этой платформе, возвращающей 0 для сдвига вправо 32-битного значения без знака на 32. Он считывает октеты в значения без знака один за другим вместе с длиной маски маски в другом байте. ; затем он принимает xor двух беззнаковых 32-битных адресов и удаляет ненужные биты. Наконец, это относится
!
к требованию возврата только двух различных значений.Примечание. Можно было бы сократить два байта, заменив их
u+3
наp
и требуя компиляции с помощью-O0
. Хотя жить опаснее, чем я хочу.Спасибо Peter Cordes за вдохновение для этого решения.
Более портативный C,
186171167 байтЗдесь я сохраню более портативную версию, которая работает 167 байт.
Эта программа берет две строки на стандартном вводе и возвращает код выхода 1, если адрес находится в подсети, и 0, если это не так. (Так что это зависит от спецификации, не требующей истинного значения для совпадений и ложного значения для несоответствий.)
Разбивка основного выражения:
a^e
,b^f
,c^g
,d^h
Вычисляет исключающий адрес и маску байт за байтом.(((a^e)<<8|b^f)<<8|c^g)<<8|d^h
затем объединяет их в одно 32-разрядное значение без знака методом Хорнера....>>32-n
затем сдвигает биты разности xor, которые не имеют отношения к маске подсети (имея в виду, что-
имеет более высокий приоритет в C, чем<<
)~0U<<32
поведение будет неопределенным при условии,unsigned
что оно равно 32 битам (это практически на всех современных платформах). С другой стороны, если n = 0, то любой адрес будет совпадать, поэтомуn&&...
даст правильный результат (используя преимущества короткого замыкания&&
).!
к выходным данным 0 или 1.-15 байт из-за комментариев потолочного кота и AdmBorkBork
-4 байта из-за комментария Питера Кордеса
источник
unsigned
. например, с помощьюchar*p=&a
thenp++,p++,p++,...
илиp--,...
as scanf."%hhu.%hhu..."
Хотя форматная строка должна быть такой, так что это значительный компромисс между этим дополнительным размером и объявлением меньшего числа переменных и возможностью сделать это(a^b)>>(32-count)
Stax , 22 байта
Запустите и отладьте его
Входные параметры разделены пробелом на стандартном входе.
Распакованный, размазанный и прокомментированный, это выглядит так.
Запустите этот
источник
Функция машинного кода x86-64,
5348 байтСписок изменений:
jz
за смену вместо использования 64-битного сдвига для обработки>>(32-0)
особого случая.setnz al
.(См. Также ответ 32-битного машинного кода Даниэля Шеплера, основанный на этом, который затем развился, чтобы использовать некоторые другие идеи, которые у нас были. Я включил мою последнюю версию этого в нижней части этого ответа.)
Возвращает ZF = 0 для хоста, не входящего в подсеть, ZF = 1 для подсети, поэтому вы можете перейти к результату с помощью
je host_matches_subnet
Может вызываться соглашением о вызовах System V в x86-64 как
bool not_in_subnet(int dummy_rdi, const char *input_rsi);
будто вы добавляетеsetnz al
.Входная строка содержит хост и сеть, разделенные ровно 1 нецифровым символом. Память после конца ширины CIDR должна содержать как минимум 3 байта без цифр перед концом страницы. (В большинстве случаев не должно быть проблемой, например, для аргумента cmdline.) 32-разрядная версия Daniel не имеет этого ограничения.
Мы запускаем один и тот же цикл синтаксического разброса в точках 3 раза, получая два IPv4-адреса и получая
/mask
как целое число в старшем байте слова. (Вот почему должна быть читаемая память после/mask
, но это не имеет значения, если есть цифры ASCII.)Мы делаем
(host ^ subnet) >> (32-mask)
для того, чтобы сместить биты хоста (те, которые допускают несовпадение), оставляя только разницу между подсетью и хостом. Чтобы решить/0
частный случай, когда нам нужно сместить на 32, мы перепрыгиваем через смещение на count = 0. (neg cl
устанавливает ZF, который мы можем разветвить и оставить в качестве возвращаемого значения, если мы не сдвигаемся.) Обратите внимание, что32-mask mod 32 = -mask
скалярные сдвиги x86 маскируют их счет на& 31
или& 63
.(не обновляется до последней версии) Попробуйте онлайн!
включая,
_start
который вызывает егоargv[1]
и возвращает статус выхода.Это работает нормально, если вы передаете аргумент командной строки, содержащий новую строку вместо пробела. Но это должно быть, а не так хорошо.
32-битная функция машинного кода x86, 38 байт
Выполните 9 целочисленных -> uint8_t синтаксических разборов и «вытолкните» их в стек, где мы вытолкнем их как dwords или используем последний, еще оставшийся в CL. Избегает чтения за концом строки вообще.
Кроме того,
dec
только 32 байта в 32-битном режиме.Тест вызывающего
источник
cmp/jcc
что вы упомянули, вы сделали что-то вродеxor edx,edx;neg cl;cmovz eax,edx;shr eax,cl
- или, может быть, у вас уже есть значение 0, которое где-то висит. (И тогда вам не понадобитсяsub cl,32
инструкция.)edi
должно быть 0, когда цикл выходит, поэтомуxor eax,edx;neg cl;cmovz eax,edi;shr eax,cl
должен работать.cmove eax,edi
имеет 3 байта, что означает «промывку» над удаленным,sub cl,32
затемshr cl,eax
сохраняет один байт более чем,shr cl,rax
а 32-разрядныйdec edi
сохраняет один байт более 64-битногоdec edi
. Моя сборка затем дает.byte 0x33
(в синтаксисе GNU binutils) = 51 дляin_subnet.size
.shr eax,cl
, по сравнениюshr %cl, %eax
с синтаксисом AT & T, ваш последний комментарий полностью изменил это.) Это немного хлопотно, чтобы обновить ответы машинного кода (и перенести_start
вызывающую программу и заново описать соглашение о вызовах для 32-битного режима.) ., так что я не могу обойтись. Чувствую себя ленивым сегодня. >. <edi
записи, записи вывода и т. Д. В итоге удалось сэкономить 2 байта в сети (По крайней мере, однажды я понял, чтоpush ecx;push ecx;push ecx
он корочеsub esp,12
; и, казалось, это была стирка, независимо от того, был ли я предварительно прокомментированedi
и использовался,std;stosb;cld
или я просто хранил с помощьюdec edi;mov [edi],al
.Желе , 23 байта
Попробуйте онлайн!
Монадическая ссылка, которая принимает адрес и подсеть, разделенные косой чертой, и возвращает 1 для true и 0 для false.
Спасибо @gwaugh за указание на недостаток в оригинале - он не смог гарантировать, что двоичный список был 32 длинным.
источник
Perl 5
-Mbigint -MSocket=:all -p
, 72 байтаПопробуйте онлайн!
источник
05AB1E , 21 байт
Занимает подсеть перед адресом.
Попробуйте онлайн или проверьте все контрольные примеры .
Объяснение:
источник
R 120 байт
функция - я вставил ".32" в первый член
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]}
и просто для удовольствия
require("iptools");w=function(a,b)ips_in_cidrs(a,b)[[2]]
что составляет 56 байт
источник
PHP ,
757371 байтВилка из @Luis Филипе де Хесус Муньос ответа «s, как автономные принимает входные данные из командной строки арг. Выходы
'1'
для Истины,''
(пустая строка) для Фасли.Попробуйте онлайн!
-2 байта, заимствуя маленький трюк @Christoph для
strtok()
. Хотя его ответ еще короче!источник
функция сборки x86,
4943 байтаЭто главным образом отправлено, чтобы удовлетворить запрос Питера Кордеса о пересмотренной версии, которую я создал. Вероятно, он может исчезнуть один раз / если он включит его в свой ответ.
Предполагается, что эта функция
esi
будет указывать на строку ввода, причем части адреса и подсети разделены пробелом или символом новой строки, а возвращаемое значение находится в флаге ZF (который по определению имеет только два возможных значения).И часть оболочки x86 Linux:
-6 байт из-за предложения Питера Кордеса вернуть значение в ZF.
источник
xor edx,edx
и заменивcmovz eax,edx
наjz .nonzero; xor eax,eax; .nonzero:
.cmovz
все еще выигрывает, если у нас есть соглашение о вызовахebx=0
.jz
надshr
сетц или рет? Мы можем поменять местами ,setnz
чтобыsetz
и вернуться1
к матчу , если это помогает. Или даже сказать , что наше возвращаемое значение является ZF. Я должен был сделать это в своем ответе. (Но я не думаю, что мы можем оправдать требование вызывающей стороны создавать константы для нас, напримерebx=0
. Мой ответ на Советы по игре в гольф в машинном коде x86 / x64 утверждает, что это слишком сильноcut
, чтобы удалить некоторые столбцы из листинга вывода NASM , потому что все мои инструкции коротки:nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Кроме того, я использовал mov вместо movzx в моем_start
звонящем, потому что состояние выхода исходит из младшего байта аргумента tosys_exit()
. Ядро игнорирует старшие байты.setnz al
послеcall in_subnet
в обертку.call
/je
, а не печать или дальнейшая передача результата. Как я указал в «советах», некоторые соглашения о вызовах системных вызовов уже делают это в реальной жизни (обычно с CF = error).Java
215 211 207 202 200 199 198 190180 байтовВыходы
true
для правдивых иfalse
ложных.Примечание. Используется
long
вместоint
потенциального смещения вправо в 32.Попробуйте онлайн!
Сохранено 1 байт благодаря floorcat
Сохранено 10 байтов благодаря Питеру Кордесу
источник
host ^ net
чтобы сместить биты, которые вы хотите удалить, вместо того, чтобы фактически создавать маску. Но я предполагаю, что Java нуждается в сравнении, чтобы создать логическое значение из целого числа. Может быть!
, потому что не имеет значения, какое из истинных или ложных вы производите для какого выхода. (Я попросил у ОП уточнения относительно того, намеревались ли они исключить 0 / ненулевое значение, и они сказали « да», они знали о последствиях этой формулировки:long
меня теряет несколько байтов, но я восполняю это тем, что могу удалить троицу и выполнить XOR, как вы предлагаете. Я проверяю что еще я могу гольф , прежде чем отправлятьДревесный уголь , 36 байт
Попробуйте онлайн! Ссылка на подробную версию кода. Принимает подсеть в качестве первого параметра и выводит информацию
-
только в том случае, если адрес находится внутри подсети. Объяснение:Разделить подсеть на
/
.Снимите маску и приведите ее к целому числу.
Вставьте адрес в массив.
Разбейте оба адреса
.
, преобразуйте их в целые числа, интерпретируйте как основание 256 и отбросьте маскированные биты.Сравните два значения.
источник
Japt , 26 байт
Попытайся
-3 байта благодаря @Shaggy!
Ввод представляет собой массив из 2 элементов
[address, subnet]
. Транспилированный JS ниже:источник
++
.g
методе меня раздражает; не могу найти способ обойти это вообще. По крайней мере, не тот, который спасет тебя байт.C # (интерактивный компилятор Visual C #) , 187 байт
Я определенно могу играть в гольф больше.
Попробуйте онлайн!
источник
C # (интерактивный компилятор Visual C #) , 134 байта
Попробуйте онлайн!
Оператор LINQ, который принимает двухэлементный массив строк в качестве входных данных в
[address, subnet]
формате.Каждый пунктирный четырехугольник преобразуется в 32 бита с использованием битовых манипуляций. Биты смещены вправо на размер подсети, и элементы сравниваются на равенство.
В то время, когда этот ответ был опубликован, было несколько ответов на C #, но ни один из них не использовал чисто битовую манипуляцию.
источник
Рубин (48 байт)
источник
====