Validação de preenchimento PKCS # 7

25

Na criptografia, o preenchimento PKCS # 7 é um esquema de preenchimento que adiciona um número de bytes N ≥ 1, em que o valor de cada byte adicionado é igual a N.

Por exemplo, Hello, World!com 13 bytes, é o seguinte em hexadecimal:

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21

Se optarmos pelo PKCS # 7 no comprimento 16, o resultado será:

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 03 03 03

E se optarmos pelo comprimento 20, o resultado será:

48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 07 07 07 07 07 07 07

Observe que no primeiro exemplo adicionamos três 03bytes e no segundo adicionamos sete 07bytes.

Sua tarefa será validar se uma sequência de caracteres (ou matriz inteira) possui o preenchimento PKCS # 7 correto. Ou seja, se o último byte da string de entrada for N, seu programa deverá verificar se os últimos N bytes da string são iguais a N.

Entrada

Uma única sequência ASCII não vazia contendo caracteres entre os pontos de código 1 e 127, inclusive. Se desejar, você pode usar a entrada como uma matriz de números inteiros.

Saída

Um valor verdadeiro se a sequência de entrada tiver preenchimento PKCS # 7 válido, caso contrário, um valor falso.

Ambas as funções e programas completos são aceitáveis. Isso é , então o objetivo é minimizar o número de bytes no seu código.

Casos de teste

A versão do array inteiro das entradas é apresentada aqui - a versão da string teria caracteres não imprimíveis para muitos dos seguintes casos de teste:

Verdade:

[1]
[1, 1]
[2, 1]
[2, 2]
[5, 6, 5, 3, 3, 3]
[1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2]
[95, 115, 80, 32, 71, 7, 122, 49, 13, 7, 7, 7, 7, 7, 7, 7, 7]
[27, 33, 54, 65, 97, 33, 52, 55, 60, 1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
[15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15]

Falsy:

[2]
[1, 2]
[5, 5, 5, 5]
[5, 6, 5, 4, 4, 4]
[3, 3, 3, 94, 3, 3]
[1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 127]
[50, 39, 94, 105, 49, 29, 74, 102, 2, 106, 44, 7, 7, 7, 7, 7, 7]
[26, 27, 59, 25, 122, 110, 20, 30, 114, 6, 9, 62, 121, 42, 22, 60, 33, 12]
Sp3000
fonte
É [1 2 3 3 3 3]verdade ou falsey? Eu acho que deveria ser verdade, mas não sou positivo.
DJMcMayhem
@DJMcMayhem Truthy
Jakube
@DJMcMayhem Truthy (isso é paralelo ao caso de teste de verdade que termina em 7s). Você pode pensar nisso como, depois de retirar, você acabaria com [1 2 3].
Sp3000 27/08/16
Certamente você pretendia colocar uma vírgula após o Hello. (É no hex.)
rici
@rici Obrigado por reparar, fixo!
Sp3000

Respostas:

8

Python, 47 34 33 bytes

lambda s:s[-1:]*s[-1]==s[-s[-1]:]

s[-1]é o último membro da lista s. Verifica se os últimos s[-1]membros da matriz de entrada ssão iguais a uma matriz s[-1]repetida várias vezes.

Recebe a entrada como uma matriz de números inteiros. Esta é uma expressão lambda; para usá-lo, atribua-o prefixando lambdacom f=.

Experimente no Ideone!

Testar:

>>> f=lambda s:s[-1:]*s[-1]==s[-s[-1]:]
>>> f([27, 33, 54, 65, 97, 33, 52, 55, 60, 1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10])
True
>>> f([50, 39, 94, 105, 49, 29, 74, 102, 2, 106, 44, 7, 7, 7, 7, 7, 7])
False

Economizou 13 bytes graças a Leaky Nun!

Guardado um byte graças a Dennis!

Cobre
fonte
def f(s)=é um byte mais curto.
ThreeFx
2
@ThreeFx você precisa retornar?
Freira vazada
@ThreeFx Sim, mas depois tenho que escrever return. A lambdaversão é 7 bytes mais curta.
Cobre
Você está certo. Desculpe.
ThreeFx
lambda s:[s[-1]]*s[-1]=s[-s[-1]:]
Freira vazada
7

Braquilog , 14 bytes

~c[A:B]t#=h~lB

Experimente online!

~c[A:B]t#=h~lB
~c[A:B]                input is concatenation of A and B
       t               B
        #=             has all equal elements
          h~lB         the first item of B is the length of B
Freira Furada
fonte
7

Pitão, 5 bytes

gFer8

RLE na entrada, pegue o último par e verifique se o número de repetições é maior ou igual ao valor.

Experimente on-line: Demonstration or Test Suite

Jakube
fonte
7

Gelatina , 5 bytes

ŒgṪṫṪ

A entrada é uma matriz de pontos de código, a saída é uma matriz não vazia (verdade) ou uma matriz vazia (falsy).

Experimente online! ou verifique todos os casos de teste .

Como funciona

ŒgṪṫṪ  Main link. Argument: A (array)

Œg     Group all runs of consecutive, equal integers.
  Ṫ    Tail; yield the last run. It should consist of n or more occurrences of n.
    Ṫ  Tail; yield n, the last element of A.
   ṫ   Dyadic tail; discard everything after the n-th element of the last run.
       If the last run was long enough, this will yield a non-empty array (truthy);
       if not, the result will be an empty array (falsy).
Dennis
fonte
6

CJam, 9 8 bytes

Agradecimentos ao Sp3000 por economizar 1 byte.

{e`W=:/}

Pega uma lista inteira como entrada e retorna 0(falso) ou um número inteiro positivo (verdade).

Suíte de teste.

Explicação

e`   e# Run-length encoding, yielding pairs of run-length R and value V.
W=   e# Get the last pair.
:/   e# Compute R/V, which is positive iff R ≥ V. Works, because V is guaranteed
     e# to be non-zero.
Martin Ender
fonte
6

05AB1E , 9 bytes

Nenhuma codificação de execução para osabie :(

¤sR¬£¬QOQ

Explicação:

¤           # Get the last element of the array
 s          # Swap the two top elements
  R         # Reverse the array
   ¬        # Get the first element
    £       # Substring [0:first element]
     ¬      # Get the first element
      Q     # Check if they are equal
       OQ   # Sum up and check if equal

Com um exemplo:

¤           # [5, 6, 5, 3, 3, 3]  3
 s          # 3  [5, 6, 5, 3, 3, 3]
  R         # 3  [3, 3, 3, 5, 6, 5]
   ¬        # 3  [3, 3, 3, 5, 6, 5]  3
    £       # 3  [3, 3, 3]
     ¬      # 3  [3, 3, 3]  3
      Q     # 3  [1, 1, 1]
       OQ   # 3==3 which results into 1

Usa a codificação CP-1252 . Experimente online!

Adnan
fonte
5

MATL , 10 bytes

Agradecemos a @Adnan por perceber um problema com uma versão anterior do código

P0hG0):)&=

Quando a entrada possui preenchimento correto, a saída é uma matriz contendo apenas um, que é verdadeiro . Quando possui preenchimento incorreto, a saída é uma matriz que contém pelo menos um zero e, portanto, é falso .

Experimente online! Ou verifique todos os casos de teste .

Explicação

P     % Implicitly take numeric array as input. Reverse the array
0h    % Append a 0. This ensures falsy output if input array is too short
G0)   % Push input again. Get its last element
:     % Range from 1 to that
)     % Apply as index into the array
&=    % 2D array of all pairwise equality comparisons. Implicitly display
Luis Mendo
fonte
@Adnan Working now
Luis Mendo
Bom, parece ser bom :)
Adnan
2
Além disso, parabéns pelo 25k! : 3
Adnan
4

Mathematica, 29 bytes

#&@@#<=Length@#&@*Last@*Split

Divida a entrada em execuções de elementos iguais, extraia o último e verifique se o primeiro elemento é menor ou igual ao comprimento dessa execução.

Martin Ender
fonte
3

Haskell, 50 bytes

import Data.List
((>=)<$>head<*>length).last.group

Toma uma matriz de números inteiros como entrada.

ThreeFx
fonte
Você precisa importar o Data.List, a menos que esteja no REPL.
xnor
2

J, 13 bytes

#~@{:-:{:{.|.

Pega a lista como um argumento único e produz, 1se for verdade e 0se for falsa.

Uso

   f =: #~@{:-:{:{.|.
   f 5 6 5 3 3 3
1
   f 5 6 5 4 4 4
0

Explicação

#~@{:-:{:{.|.  Input: array A
           |.  Reverse A
       {:      Get the last value in A
         {.    Take that many values from the reverse of A
   {:          Get the last value in A
#~@            Make a list with that many copies of the last value
     -:        Test if the list of copies matches the sublist of A and return
milhas
fonte
@ randomra Um caso como 3 4 3 3 3teria ~.como 3 4que a última linha de =é 0 1 0 0 0. Eu acho que operar no reverso como {:*/@{.0{=@|.deve funcionar, mas acaba com 13 bytes também.
miles
Certo, boa captura. Eu senti falta disso.
Random # 29/16
2

Brain-Flak , 54 bytes

(({})[()]){({}[()]<({}[({})]){<>}{}>)}{}{<>(<(())>)}{}

Entrada é uma lista de números inteiros, a saída é 1 para verdade e vazia para falsey.

Explicação

(({})[()]){ Loop a number of times equal to the last integer in the input - 1
    ({}[()] Handle loop counter
        < Silently...
            ({}[({})]) Replace the last code point in the string with its difference with the code point before it
            {<>} If the difference is not zero then switch stacks
            {} Discard the difference
        > End silently
    ) Handle loop counter
} End loop
{} Discard the loop counter
{<>(<(())>)} If the top of the current stack is not 0 (which means we have not switched stacks push 0 then 1
{} Discard the top of the stack (either nothing if falsey or 0 if truthy)

O loop não termina imediatamente quando um valor que resultaria em um retorno falsey é encontrado. Em vez disso, é alternado para a outra pilha que está vazia e gasta o restante de suas iterações comparando 0 e 0.

0 '
fonte
1
Oh, ei, prazer em vê-lo aqui! Bem vindo ao site!
DJMcMayhem
1

Lote, 101 bytes

@for %%a in (%*)do @set/an=%%a,c=0
@for %%a in (%*)do @set/ac+=1,c*=!(n-%%a)
@if %c% geq %n% echo 1

Pega a entrada como parâmetros da linha de comando, faz um loop sobre todos eles para que ele possa inserir o último, faz um nloop sobre todos novamente para contar a sequência de ns à direita , finalmente imprimindo 1se a contagem for pelo menos igual a n. Como alternativa, se a impressão 0ou um valor diferente de zero for aceitável, altere a última linha para 93 bytes para 93 bytes @cmd/cset/ac/n.

Neil
fonte
1

Haskell, 49 bytes

f s|x<-(==last s)=x.length.fst.span x.reverse$s

Experimente em Ideone.

Versão mais curta que retorna Truepor verdade e Falseou uma exceção por falsidade:

((==).head>>=all).(head>>=take).reverse
Laikoni
fonte
1

Dyalog APL , 10 bytes

(⊃∧.=⊃↑⊢)⌽

É o primeiro
∧.=all-igual
o primeiro
n retirado
o
argumento inverso?

TryAPL online!

Adão
fonte
2
Quantos bytes?
Conor O'Brien
@ ConorO'Brien Desculpe, esqueci de preencher o padrão.
Adám 28/08/16
1

Javascript (ES6), 51 47 41 bytes

a=>(r=k=>a.pop()^n?k<2:r(k-1))(n=a.pop())

Exemplos:

let f =
a=>(r=k=>a.pop()^n?k<2:r(k-1))(n=a.pop())

console.log(f([5, 6, 5, 3, 3, 3]))
console.log(f([5, 6, 5, 4, 4, 4]))

Arnauld
fonte
1

C 91 Bytes

int f(int*l){int n;for(n=0;l[++n];);l+=n-1;for(int i=*l;i;)if(l[-i--+1]^*l||n<*l)return 0;}

Entrada: um ponteiro para uma matriz terminada em nulo.
Saída: retorna 0para preenchimento inválido e diferente de zero para válido (o último elemento na matriz)

Exemplos:

int a[] = {5, 6, 5, 3, 3, 3, 0};
printf("%d\n", f(&a[5], 6));

int b[] = {1, 1, 2, 2, 1, 1, 2, 2, 1, 1, 2, 2, 0};
printf("%d\n", f(&b[11],12 ));

int m[] = {5, 6, 5, 4, 4, 4, 0};
printf("%d\n", f(&m[5], 6));

int n[] = {3, 3, 3, 94, 3, 3, 0};
printf("%d\n", f(&n[5], 6));

Dá:

3
2
0
0

Isso depende de comportamento indefinido. Se o preenchimento for válido, não há declaração de retorno, mas usar gcc -std=c99isso retorna o último elemento da matriz que foi passada (pelo menos na minha máquina).

Riley
fonte
1

Braquilog , 6 bytes

a₁=.l∈

Experimente online!

Resultados através do predicado sucesso ou fracasso, como faz a resposta Brachylog v1 da Leaky Nun. Também adota uma abordagem semelhante, mas sai muito mais curta.

a₁        There exists a suffix of the input
  =       the elements of which are all equal
   .      which is the output variable
    l     the length of which
     ∈    is an element of
          the output variable.

Braquilog , 6 bytes

ḅt.l≥∈

Experimente online!

Uma versão alternativa que sai da mesma extensão que se inspira na resposta de Dennis 'Jelly.

 t        The last
ḅ         block of consecutive equal elements of the input
  .       is the output variable
   l      the length of which
    ≥     is greater than or equal to
     ∈    an element of
          the output variable.
String não relacionada
fonte
0

Retina , 34 bytes

A contagem de bytes assume a codificação ISO 8859-1.

.+
$*
\b(1(1)*)(?<-2>¶\1)*$(?(2)!)

Entrada é uma lista de números inteiros separados por avanço de linha. Imprime 0ou 1.

Experimente online! (A primeira linha habilita um conjunto de testes, onde há um caso de teste separado por espaço.)

Uma ideia alternativa que termina em 35 bytes e imprime 0ou um número inteiro positivo:

.+
$*
\b(?=(1+)(¶\1)*$)(?<-2>1)*1\b
Martin Ender
fonte
0

Javascript (ES5), 89 bytes

function(b){for(var d=b[b.length-1],c=0;c<d;c++)if(b[b.length-c-1]!=d)return!1;return!0};

Ungolfed:

function a(arr){
var b=arr[arr.length-1];
for(var i=0;i<b;i++){
    if(arr[arr.length-i-1]!=b)return false;
}
return true;
}
Paul Schmitz
fonte
0

Brain-Flak 84 bytes

100000000 me derrotou aqui

Experimente Online!

((({}))){({}[()]<(({})<([{}]{}<>)<>>)>)}<>([])({<{}>{}<([])>}{}<(())>){((<{}{}>))}{}

Recebe entrada como matriz de números inteiros.

Explicação para vir.

Aqui está uma versão de 64 bytes que gera o não da resposta:

((({}))){({}[()]<(({})<([{}]{}<>)<>>)>)}<>([])({<{}>{}<([])>}{})
Assistente de Trigo
fonte