Validación de relleno PKCS # 7

25

En criptografía, el relleno PKCS # 7 es un esquema de relleno que agrega un número de bytes N ≥ 1, donde el valor de cada byte agregado es igual a N.

Por ejemplo, Hello, World!que tiene 13 bytes, es el siguiente en hexadecimal:

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

Si elegimos PKCS # 7 pad a la longitud 16, entonces el resultado es:

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

Y si elegimos rellenar hasta la longitud 20, entonces el resultado es:

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

Tenga en cuenta que en el primer ejemplo agregamos tres 03bytes, y en el segundo agregamos siete 07bytes.

Su tarea será validar si una cadena (o matriz de enteros) tiene el relleno PKCS # 7 correcto. Es decir, si el último byte de la cadena de entrada es N, entonces su programa debe verificar que los últimos N bytes de la cadena sean iguales a N.

Entrada

Una sola cadena ASCII no vacía que contiene caracteres entre los puntos de código 1 y 127 inclusive. Si lo desea, puede tomar la entrada como una matriz de enteros en su lugar.

Salida

Un valor verdadero si la cadena de entrada tiene un relleno PKCS # 7 válido; de lo contrario, un valor falso.

Ambas funciones y programas completos son aceptables. Este es el , por lo que el objetivo es minimizar el número de bytes en su código.

Casos de prueba

Aquí se presenta la versión de matriz entera de entradas: la versión de cadena tendría caracteres no imprimibles para muchos de los siguientes casos de prueba:

Verdad:

[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
fuente
¿Es [1 2 3 3 3 3]veraz o falsey? Yo creo que debería ser Truthy pero no soy positivo.
DJMcMayhem
@DJMcMayhem Truthy
Jakube
@DJMcMayhem Truthy (esto es paralelo al caso de prueba de verdad que termina en 7s). Puedes pensar que, después de desnudarte, terminarías con [1 2 3].
Sp3000
Seguramente querías poner una coma después de Hola. (Está en el hex.)
rici
@rici Gracias por notarlo, arreglado!
Sp3000

Respuestas:

8

Python, 47 34 33 bytes

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

s[-1]es el último miembro de la lista s. Comprueba que los últimos s[-1]miembros de la matriz de entrada sson iguales a una matriz s[-1]repetida tantas veces.

Toma datos como una matriz de enteros. Esta es una expresión lambda; para usarlo, asígnele el prefijo lambdacon f=.

Pruébalo en Ideone!

Probar:

>>> 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

¡Guardado 13 bytes gracias a Leaky Nun!

¡Ahorré un byte gracias a Dennis!

Cobre
fuente
def f(s)=Es un byte más corto.
ThreeFx
2
@ThreeFx necesitas regresar?
Leaky Nun
@ThreeFx Sí, pero luego tengo que escribir return. La lambdaversión es 7 bytes más corta.
Cobre
Tienes razón. Lo siento.
ThreeFx
lambda s:[s[-1]]*s[-1]=s[-s[-1]:]
Leaky Nun
7

Brachylog , 14 bytes

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

Pruébalo en línea!

~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
Monja permeable
fuente
7

Pyth, 5 bytes

gFer8

RLE en la entrada, tome el último par y verifique si el número de repeticiones es mayor o igual que el valor.

Pruébelo en línea: Demostración o conjunto de pruebas

Jakube
fuente
7

Jalea , 5 bytes

ŒgṪṫṪ

La entrada es una matriz de puntos de código, la salida es una matriz no vacía (verdad) o una matriz vacía (falsa).

Pruébalo en línea! o verificar todos los casos de prueba .

Cómo 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
fuente
6

CJam, 9 8 bytes

Gracias a Sp3000 por guardar 1 byte.

{e`W=:/}

Toma una lista entera como entrada y devuelve 0(falso) o un entero positivo (verdadero).

Banco de pruebas.

Explicación

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
fuente
6

05AB1E , 9 bytes

No hay codificaciones de longitud de ejecución para osabie :(

¤sR¬£¬QOQ

Explicación:

¤           # 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

Con un ejemplo:

¤           # [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

Utiliza la codificación CP-1252 . Pruébalo en línea!

Adnan
fuente
5

MATL , 10 bytes

Gracias a @Adnan por notar un problema con una versión anterior del código

P0hG0):)&=

Cuando la entrada tiene el relleno correcto, la salida es una matriz que contiene solo unos, lo cual es cierto . Cuando tiene un relleno incorrecto, la salida es una matriz que contiene al menos un cero, por lo que es falso .

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación

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
fuente
@Adnan Trabajando ahora
Luis Mendo
Bonito, se ve bien :)
Adnan
2
Además, ¡felicidades por 25k! : 3
Adnan
4

Mathematica, 29 bytes

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

Divida la entrada en corridas de elementos iguales, extraiga el último y verifique que su primer elemento sea menor o igual a la longitud de esa corrida.

Martin Ender
fuente
3

Haskell, 50 bytes

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

Toma una matriz de enteros como entrada.

ThreeFx
fuente
Necesita importar Data.List a menos que esté en REPL.
xnor
2

J, 13 bytes

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

Toma la lista como un argumento único y 1muestra 0si es verdadera y si es falsa.

Uso

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

Explicación

#~@{:-:{:{.|.  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
millas
fuente
@randomra Un caso como 3 4 3 3 3tendría ~.como 3 4para que la última fila de =es 0 1 0 0 0. Creo que operar en el reverso como {:*/@{.0{=@|.debería funcionar, pero también termina en 13 bytes.
millas
Bien, buena captura. Me lo perdí.
randomra
2

Brain-Flak , 54 bytes

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

La entrada es una lista de enteros, la salida es 1 para verdadero y vacía para falsey.

Explicación

(({})[()]){ 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)

El ciclo no termina inmediatamente cuando se encuentra un valor que resultaría en un retorno de falsey. En cambio, se cambia a la otra pila que está vacía y gasta el resto de sus iteraciones comparando 0 y 0.

0 '
fuente
1
¡Oh, hola, me alegro de verte aquí! Bienvenido al sitio!
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

Toma la entrada como parámetros de la línea de comandos, recorre todos ellos para que pueda ingresar el último n, los repite nuevamente para contar la serie de ns finales , finalmente imprime 1si el conteo es al menos igual a n. Alternativamente, si la impresión 0o un valor distinto de cero es aceptable, entonces para 93 bytes, cambie la última línea a @cmd/cset/ac/n.

Neil
fuente
1

Haskell, 49 bytes

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

Pruébalo en Ideone.

Versión más corta que devuelve Trueverdad y / Falseo una excepción por falsedad:

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

Dyalog APL , 10 bytes

(⊃∧.=⊃↑⊢)⌽

Es el primero en
∧.=todo igual a
la primera
n tomada desde
el
argumento inverso?

TryAPL en línea!

Adán
fuente
2
Cuantos bytes
Conor O'Brien
@ ConorO'Brien Lo siento, olvidé completar la repetitiva.
Adám
1

Javascript (ES6), 51 47 41 bytes

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

Ejemplos:

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
fuente
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: un puntero a una matriz terminada en nulo.
Salida: devuelve el 0relleno no válido y no es cero para el válido (el último elemento de la matriz)

Ejemplos:

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));

Da:

3
2
0
0

Esto se basa en un comportamiento indefinido. Si el relleno es válido, no hay una declaración de devolución, pero el uso de gcc -std=c99este devuelve el último elemento de la matriz que se pasó (al menos en mi máquina).

Riley
fuente
1

Brachylog , 6 bytes

a₁=.l∈

Pruébalo en línea!

Salidas a través del éxito o fracaso del predicado, como lo hace la respuesta Brachylog v1 de Leaky Nun. También adopta un enfoque similar, pero sale mucho más corto.

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.

Brachylog , 6 bytes

ḅt.l≥∈

Pruébalo en línea!

Una versión alternativa que tiene la misma longitud que se inspira en la respuesta 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.
Cadena no relacionada
fuente
0

Retina , 34 bytes

El recuento de bytes asume la codificación ISO 8859-1.

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

La entrada es una lista de enteros separada por salto de línea. Impresiones 0o 1.

Pruébalo en línea!(La primera línea habilita un conjunto de pruebas, donde hay un caso de prueba separado por espacios por línea).

Una idea alternativa que termina en 35 bytes e imprime 0o un entero positivo:

.+
$*
\b(?=(1+)(¶\1)*$)(?<-2>1)*1\b
Martin Ender
fuente
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};

Sin golf:

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
fuente
0

Brain-Flak 84 bytes

100000000 me ganó aquí

¡Pruébelo en línea!

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

Toma entrada como un conjunto de enteros.

Explicación por venir.

Aquí hay una versión de 64 bytes que genera el no de la respuesta:

((({}))){({}[()]<(({})<([{}]{}<>)<>>)>)}<>([])({<{}>{}<([])>}{})
Asistente de trigo
fuente