Desafio
Dado um IPv4 address
na notação quad-dotted, e um IPv4 subnet
na notação CIDR , determine se ele address
está no subnet
. Emita um valor distinto e consistente se estiver no subnet
e um valor distinto e consistente separado se não estiver no subnet
. Os valores de saída não precisam necessariamente ser verdade / falsey no seu idioma.
Resumo da notação de sub-rede CIDR
Os endereços de rede IPv4 têm 32 bits de comprimento, divididos em quatro grupos de 8 bits para facilitar a leitura. A notação de sub-rede CIDR é uma máscara do número especificado de bits, iniciando à esquerda. Por exemplo, para uma /24
sub - rede, isso significa que os 8 bits mais à direita do endereço estão disponíveis nessa sub-rede. Assim, dois endereços separados por no máximo 255
e com a mesma máscara de sub-rede estão na mesma sub-rede. Observe que o CIDR válido possui todos os bits do host (lado direito) desabilitados (zeros).
xxxxxxxx xxxxxxxx xxxxxxxx 00000000
^--- subnet mask ---^ ^-hosts-^
Para outro exemplo, uma /32
sub - rede especifica que todos os bits são a máscara de sub-rede, significando essencialmente que apenas um host é permitido por /32
.
xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
^--- subnet mask ---^
Exemplos:
Usando True
para "na sub-rede" e False
para "não na sub-rede" como saída:
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
Regras e esclarecimentos
- Como a análise de entrada não é o ponto interessante desse desafio, você garante endereços IPv4 válidos e máscaras de sub-rede.
- A entrada e a saída podem ser fornecidas por qualquer método conveniente .
- Você pode imprimir o resultado em STDOUT ou retorná-lo como resultado da função. Indique na sua submissão quais valores a saída pode assumir.
- Um programa completo ou uma função são aceitáveis.
- As brechas padrão são proibidas.
- Isso é código-golfe, portanto todas as regras usuais de golfe se aplicam e o código mais curto (em bytes) vence.
fonte
10.0.0.1/10.0.0.0”/16
?1.255.1.1/8
é uma expressão CIDR válida , representando o host1.255.1.1
na rede1.0.0.0
com uma máscara de sub-rede de255.0.0.0
. No entanto, o desafio pede o número da rede e a sub-rede especificamente na notação CIDR, que1.255.1.1/8
não é uma combinação válida de número de rede e sub-rede.Respostas:
Python 3 (62 bytes)
Muito simples:
fonte
ip_adress
objeto e umip_network
objeto constituemany convenient method
, possivelmente deixando o Python vencer, a menos que uma linguagem de golfe baseada em python os tenha como seus tipos?(host^net)>>(32-mask)
é de apenas 10 bytes. Mas é meio caminho andado para tarefas que não envolvem listas de listas ou mapear uma função em uma lista, porque muitas operações escalares podem ser feitas com uma instrução de 2 ou 3 bytes e podem ser construídos loops em poucos bytes.C # (Compilador Visual C #) , 250 + 31 = 281 bytes
Bytecount inclui
using System;using System.Linq;
Experimente online!
Eu escrevi isso em JS assim que o desafio foi lançado, mas Arnauld me venceu com uma resposta muito melhor, então aqui está em C #.
Definitivamente muito espaço para jogar golfe.
Explicação:
A função consiste em uma subfunção chamada
h
:Essa subfunção divide o endereço IP
.
, converte cada número em uma seqüência de caracteres binária, coloca cada uma das strings à esquerda com0
8 bits de comprimento e concatena as seqüências de caracteres em uma seqüência de caracteres binária de 32 bits.Isso é feito imediatamente no local
a=h(a);
especificado no endereço IP.Em seguida, dividimos a máscara de sub-rede em um endereço IP e um número de máscara com
c=b.Split('/');
O componente Endereço IP também é passado através de nossa sub-função:
b=h(c[0]);
e o número da máscara é analisado para um número inteiro:var d=int.Parse(c[1]);
Finalmente, pegamos os primeiros
d
bits das duas cadeias binárias (onded
está o número da máscara) e os comparamos:return a.Substring(0,d)==b.Substring(0,d);
fonte
rPad
é um incorporador de strings. link pastebin para o link TIO que é muito longo sozinhoShell Linux POSIX (com net-tools / iputils) (34 bytes sem finalização, 47 bytes com finalização)
O que é mais adequado para analisar máscaras e endereços de rede do que os próprios utilitários de rede? :)
Aviso: o script é potencialmente prejudicial à sua conectividade com a Internet, execute com cuidado.
Entrada: o script usa o endereço IP testado como primeiro argumento e a sub-rede testada. como segundo argumento.
Saída: o script retornará um valor de verdade (0) se o primeiro argumento do script pertencer à sub-rede indicada no segundo argumento. Caso contrário, nunca será encerrado.
Pressupostos: o script deve ser executado como usuário raiz, em um ambiente limpo ( ou seja , nenhuma outra rota do buraco negro foi definida pelo administrador e, se uma instância anterior do script foi executada, a rota do buraco negro criada foi removida ) O script também assume uma "conexão com a Internet em funcionamento" ( ou seja , uma rota padrão válida está presente).
Explicação:
Criamos uma rota de buraco negro para a sub-rede especificada. Em seguida, testamos a conectividade com o endereço IP fornecido usando ping . Se o endereço não pertencer à sub-rede (e como assumimos uma conexão com a Internet configurada corretamente), o ping tentará enviar pacotes para esse endereço. Observe que, se esse endereço realmente responder, não importa, pois o ping continuará tentando para sempre. Por outro lado, se o endereço pertencer à sub-rede, o ping falhará com ENETUNREACH e retornará 2 e, como negamos o comando, o script será bem-sucedido.
Exemplo
Teste se 5.5.5.5 pertence a 8.8.8.0/24
(Limpe
sudo ip route del 8.8.8.0/24
após executar o comando).Teste se 5.5.5.5 pertence a 5.5.5.0/24:
(Limpe
sudo ip route del 5.5.5.0/24
após executar o comando).Teste se 8.8.8.8 pertence a 5.5.5.0/24:
(Limpe
sudo ip route del 5.5.5.0/24
após executar o comando).Versão de 47 bytes, se não permitirmos scripts que não terminem
De acordo com o comentário de @ Grimy, aqui está a versão que sempre termina e retorna 0 (verdadeiro) se o endereço estiver na sub-rede e 1 (falso) caso contrário. Fazemos o término do ping com o
-c1
sinalizador que limita o número de pacotes enviados a 1. Se o endereço respondeu, o ping retornará 0 e, caso contrário, o ping retornará 1. Somente se o endereço pertencer à sub-rede com o buraco negro, o ping retornará 2, que é, portanto, contra o que testamos no último comando.fonte
ping
que morreria do SIGPIPE se estivesse rodando com o stdout + stderr canalizado para outro programa, e o leitor fechou o pipe. E esse é o caso de uso mais provável, porque o status de saída pode ser bem-sucedido de qualquer maneira (se adicionarmos uma-c1
opção para executar ping para definir a contagem)var=$(/a.sh)
. você precisaria de um leitor que parasse depois de decidir, em vez de ler toda a saída e depois analisá-la.ping
que terminará em menos de, digamos, um segundo no caso de um endereço oculto). Eu adicionei uma versão final para 13 bytes extras! :)JavaScript (ES6), 82 bytes
Toma entrada como
(address)(subnet)
. Retorna um valor booleano.Experimente online!
fonte
PHP ,
1019288 bytes-13 bytes de @gwaugh
Experimente online!
fonte
function($i,$r){return!((ip2long($i)^ip2long(strtok($r,'/')))>>32-strtok(_));}
strtok()
. O seu é 4 bytes mais curto do que minha resposta muito semelhante abaixo. Adereços!PowerPC / PPC64 C,
116114 bytes(Testado no x86_64 Ubuntu 18.04 usando powerpc64-linux-gnu-gcc -static e qemu-user.)
O programa pega as duas linhas na entrada padrão e, como código de saída, retorna 1 se o endereço corresponder e 0 se não corresponder. (Portanto, isso depende da especificação que não exige um valor verdadeiro para uma correspondência e um valor de falsey para uma incompatibilidade.) Observe que, se você estiver executando interativamente, precisará sinalizar EOF (
^D
) três vezes após entrar na segunda linha.Isso depende do PowerPC ser big-endian e também dessa plataforma retornar 0 para deslocar para a direita um valor não assinado de 32 bits por 32. Ele lê os octetos em valores não assinados um a um, juntamente com o comprimento da máscara de rede em outro byte ; então pega o xor dos dois endereços de 32 bits não assinados e desloca os bits irrelevantes. Por fim, aplica-se
!
a satisfazer o requisito de retornar apenas dois valores distintos.Nota: pode ser possível raspar dois bytes, substituindo
u+3
comp
e exigindo compilação com-O0
. Mas isso é viver de maneira mais perigosa do que eu gostaria.Agradecemos a Peter Cordes pela inspiração para esta solução.
C mais portátil,
186171167 bytesAqui vou preservar uma versão mais portátil que executa 167 bytes.
Este programa pega as duas linhas na entrada padrão e retorna o código de saída 1 se o endereço estiver na sub-rede e 0 se não estiver. (Portanto, isso depende da especificação que não exige um valor verdadeiro para correspondências e um valor de falsey para não correspondências.)
Um detalhamento da expressão principal:
a^e
,b^f
,c^g
,d^h
Calcula o XOR do endereço e a máscara byte-por-byte.(((a^e)<<8|b^f)<<8|c^g)<<8|d^h
depois os combina em um único valor de 32 bits não assinado por um método semelhante ao Horner....>>32-n
então desloca os bits da diferença xor que não são relevantes para a máscara de sub-rede (lembrando que-
tem maior precedência em C que<<
)~0U<<32
o comportamento indefinido será assumido comounsigned
sendo de 32 bits (que está em praticamente todas as plataformas atuais). Por outro lado, se n = 0, qualquer endereço corresponderá e, portanton&&...
, fornecerá o resultado correto (aproveitando o comportamento de curto-circuito de&&
).!
a saída 0 ou 1.-15 bytes devido a comentários de ceilingcat e AdmBorkBork
-4 bytes devido a comentário de Peter Cordes
fonte
unsigned
. por exemplo, comchar*p=&a
entãop++,p++,p++,...
oup--,...
como scanf args. A string de formato precisaria ser"%hhu.%hhu..."
, portanto, é uma troca significativa entre esse tamanho extra vs. declarar menos vars e ser capaz de fazer(a^b)>>(32-count)
Stax , 22 bytes
Execute e depure
Os parâmetros de entrada são separados por espaço na entrada padrão.
Descompactado, não jogado e comentado, parece com isso.
Execute este
fonte
função de código de máquina x86-64,
5348 byteschangelog:
jz
durante o turno em vez de usar um turno de 64 bits para lidar com o>>(32-0)
caso especial.setnz al
.(Veja também a resposta de código de máquina de Daniel Schepler de 32 bits com base nisso, que evoluiu para usar algumas outras idéias que tínhamos. Estou incluindo minha versão mais recente disso na parte inferior desta resposta.)
Retorna ZF = 0 para o host que não está na sub-rede, ZF = 1 para na sub-rede, para que você possa ramificar o resultado com
je host_matches_subnet
É possível chamar com a convenção de chamada do System V x86-64 como
bool not_in_subnet(int dummy_rdi, const char *input_rsi);
se você adicionassesetnz al
.A sequência de entrada contém o host e a rede, separados por exatamente 1 caractere sem dígito. A memória após o final da largura do CIDR deve conter pelo menos 3 bytes sem dígito antes do final de uma página. (Na maioria dos casos, não deve ser um problema, como para um argumento cmdline.) A versão de 32 bits de Daniel não tem essa limitação.
Executamos o mesmo loop de análise quad-dotted-quad três vezes, obtendo os dois endereços IPv4 e obtendo o
/mask
número inteiro no byte alto de um dword. (É por isso que deve haver memória legível após o/mask
, mas não importa se há dígitos ASCII.)Fazemos
(host ^ subnet) >> (32-mask)
para mudar os bits do host (os que podem ser incompatíveis), deixando apenas a diferença entre a sub-rede e o host. Para resolver o/0
caso especial em que precisamos mudar em 32, saltamos sobre o deslocamento na contagem = 0. (neg cl
define ZF, no qual podemos ramificar e deixar o valor de retorno se não mudarmos.) Observe que32-mask mod 32 = -mask
as mudanças escalares x86 mascaram sua contagem por& 31
ou& 63
.(não atualizado com a versão mais recente) Experimente online!
incluindo um
_start
que chamaargv[1]
e retorna um status de saída.Funciona bem se você passar uma linha de comando arg contendo uma nova linha em vez de um espaço. Mas tem que ser em vez disso , não tão bem.
função de código de máquina x86 de 32 bits, 38 bytes
Faça 9 inteiro -> uint8_t analise e "empurre" eles na pilha, onde os exibimos como dwords ou usamos o último ainda no CL. Evita a leitura além do final da string.
Além disso,
dec
possui apenas 1 byte no modo de 32 bits.Chamador de teste
fonte
cmp/jcc
que você mencionou, fizesse algo comoxor edx,edx;neg cl;cmovz eax,edx;shr eax,cl
- ou talvez você já tenha um valor 0 em algum lugar. (E então você não precisaria dassub cl,32
instruções.)edi
deve ser 0 quando o loop sair, portanto,xor eax,edx;neg cl;cmovz eax,edi;shr eax,cl
deve funcionar.cmove eax,edi
tem 3 bytes, que é uma lavagem sobre os removidossub cl,32
eshr cl,eax
salva um byteshr cl,rax
e 32 bitsdec edi
salva um byte sobre 64 bitsdec edi
. Minha montagem então fornece.byte 0x33
(na sintaxe GNU binutils) = 51 parain_subnet.size
.shr eax,cl
,shr %cl, %eax
em comparação com a AT&T, seu último comentário reverteu isso.) É um pouco complicado atualizar as respostas do código da máquina (e portar o_start
chamador e re-descrever a convenção de chamada no modo de 32 bits.) .), para que eu não consiga resolver isso. Sentindo-se preguiçoso hoje. >. <edi
gravação, escrever a saída etc., acabou economizando 2 bytes na rede. (Pelo menos uma vez eu percebi quepush ecx;push ecx;push ecx
era mais curto do quesub esp,12
; e parecia ser uma lavagem se eu predecediedi
e useistd;stosb;cld
ou se apenas armazenei usandodec edi;mov [edi],al
.)Gelatina , 23 bytes
Experimente online!
Link monádico que pega o endereço e a sub-rede separados por uma barra e retorna 1 para verdadeiro e 0 para falso.
Agradecemos a @gwaugh por apontar uma falha no original - ela falhou em garantir que a lista binária tivesse 32 comprimentos.
fonte
Perl 5
-Mbigint -MSocket=:all -p
, 72 bytesExperimente online!
fonte
05AB1E , 21 bytes
Leva a sub-rede antes do endereço.
Experimente online ou verifique todos os casos de teste .
Explicação:
fonte
R 120 bytes
uma função - colei ".32" no primeiro termo
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]}
e apenas por diversão:
require("iptools");w=function(a,b)ips_in_cidrs(a,b)[[2]]
que é 56 bytes
fonte
PHP ,
7573, 71 bytesUma bifurcação da resposta de @Luis felipe De jesus Munoz , como uma autônoma recebendo informações dos argumentos da linha de comando. Saídas
'1'
para Truthy,''
(string vazia) para Fasley.Experimente online!
-2 bytes emprestando o pequeno truque de @Christoph para
strtok()
. Sua resposta ainda é mais curta!fonte
função de montagem x86,
49.43 bytesIsso é publicado principalmente para atender à solicitação de Peter Cordes da versão revisada que eu criei. Provavelmente pode desaparecer uma vez / se ele incorporá-lo em sua resposta.
Essa função espera
esi
apontar para uma sequência de entrada, com as partes de endereço e sub-rede separadas por um espaço ou por um caractere de nova linha, e o valor de retorno está no sinalizador ZF (que, por definição, possui apenas dois valores possíveis).E a parte do wrapper x86 Linux:
-6 bytes devido à sugestão de Peter Cordes para retornar o valor em ZF.
fonte
xor edx,edx
e substituindocmovz eax,edx
porjz .nonzero; xor eax,eax; .nonzero:
.cmovz
ainda ganha se tivermos convocado convençãoebx=0
.jz
passarshr
para o setz ou o ret? Podemos trocar osetnz
parasetz
e retornar1
para uma partida, se isso ajudar. Ou até mesmo diga que nosso valor de retorno é ZF. Eu deveria ter feito isso na minha resposta. (Mas acho que não podemos justificar exigir que o chamador crie constantes para nós, comoebx=0
. Minha resposta em Dicas para jogar golfe em código de máquina x86 / x64 argumenta que esticaria muito demais uma convenção de chamada personalizada.cut
para remover algumas colunas da lista de saída NASM porque todas as minhas instruções são curtas:nasm -felf foo.asm -l/dev/stdout | cut -b -34,$((34+6))-
. Além disso, usei mov em vez de movzx no meu_start
chamador porque o status de saída vem do byte baixo do arg parasys_exit()
. O kernel ignora os bytes mais altos.setnz al
depoiscall in_subnet
no wrapper.call
/je
, em vez de imprimir ou repassar o resultado. Como apontei nas "dicas", algumas convenções de chamada de sistema já fazem isso na vida real (geralmente com CF = erro).Java
215 211 207 202 200 199 198 190180 bytesSaídas
true
para verdade efalse
falsidade.Nota: Isso usa em
long
vez deint
para o possível deslocamento à direita de 32.Experimente online!
Guardado 1 byte graças a ceilingcat
Economizou 10 bytes graças a Peter Cordes
fonte
host ^ net
para alterar os bits que deseja remover, em vez de realmente criar uma máscara. Mas acho que o Java precisa de uma comparação para criar um booleano a partir de um número inteiro. Talvez a!
, porque não importa qual verdadeiro ou falso você produz para qual saída. (Solicitei esclarecimentos ao OP sobre se pretendiam excluir 0 / diferente de zero, e eles disseram que estavam cientes das consequências dessa redação:long
me perder alguns bytes, mas eu o compenso removendo o ternário e fazendo o XOR como você sugere. Estou verificando o que mais posso jogar golfe antes de postarCarvão , 36 bytes
Experimente online! Link é a versão detalhada do código. Toma a sub-rede como o primeiro parâmetro ee produz
-
somente se o endereço estiver dentro da sub-rede. Explicação:Divida a sub-rede
/
.Remova a máscara e jogue-a no número inteiro.
Envie o endereço para a matriz.
Divida os dois endereços
.
, converta-os em números inteiros, interprete como base 256 e descarte os bits mascarados.Compare os dois valores.
fonte
Japonês , 26 bytes
Tente
-3 bytes graças a @Shaggy!
Entrada é uma matriz com 2 elementos
[address, subnet]
. JS transpilado abaixo:fonte
++
.g
método está me irritando; não consigo descobrir uma maneira de contornar isso. Pelo menos não um que economize um byte.C # (compilador interativo do Visual C #) , 187 bytes
Definitivamente, eu posso jogar mais isso.
Experimente online!
fonte
C # (compilador interativo do Visual C #) , 134 bytes
Experimente online!
Instrução LINQ que usa uma matriz de cadeia de 2 elementos como entrada no
[address, subnet]
formato.Cada quadra pontilhada é convertida em 32 bits de comprimento usando a manipulação de bits. Os bits são deslocados à direita pelo tamanho da sub-rede e os elementos são comparados quanto à igualdade.
Havia algumas respostas de C # no momento em que essa resposta foi postada, mas nenhuma que usava manipulação de bits pura.
fonte
Ruby (48 bytes)
fonte
====