Проверка дополнения PKCS # 7

25

В криптографии заполнение PKCS # 7 является схемой заполнения, которая добавляет количество байтов N ≥ 1, где значение каждого добавленного байта равно N.

Например, Hello, World!который имеет 13 байтов, является следующим в шестнадцатеричном виде:

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

Если мы выберем для пэда PKCS # 7 длину 16, то результатом будет:

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

И если мы выберем длину до 20, то результат будет следующим:

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

Обратите внимание, что в первом примере мы добавляем три 03байта, а во втором мы добавляем семь 07байтов.

Ваша задача будет проверить, имеет ли строка (или целочисленный массив) правильное заполнение PKCS # 7. То есть, если последний байт входной строки равен N, то ваша программа должна проверить, что последние N байтов строки равны N.

вход

Одна непустая строка ASCII, содержащая символы между кодовыми точками 1 и 127 включительно. Если вы хотите, вы можете принять входные данные в виде массива целых чисел.

Выход

Truthy значение , если входная строка имеет действительный PKCS # 7 обивки, в противном случае falsy значение.

Обе функции и полные программы являются приемлемыми. Это , поэтому цель состоит в том, чтобы минимизировать количество байтов в вашем коде.

Контрольные примеры

Здесь представлена ​​версия входных данных целочисленного массива - строковая версия будет иметь непечатаемые символы для многих из следующих тестовых случаев:

Truthy:

[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
источник
Это [1 2 3 3 3 3]правда или ложь? Я думаю, что это должно быть правдой, но я не уверен.
DJMcMayhem
@DJMcMayhem Truthy
Якуб
@DJMcMayhem Truthy (это параллельно с правдоподобным тестовым примером, оканчивающимся на 7s). Вы можете думать об этом, как после раздевания, вы в конечном итоге [1 2 3].
Sp3000
Конечно, вы хотели поставить запятую после Привет. (Это в
гексе
@rici Спасибо, что заметили, исправлено!
Sp3000

Ответы:

8

Python, 47 34 33 байта

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

s[-1]последний член списка s. Проверяет, что последние s[-1]члены входного массива sсовпадают с массивом s[-1]повторяющихся столько раз.

Принимает ввод как массив целых чисел. Это лямбда-выражение; использовать его, назначить его предваряя lambdaс f=.

Попробуйте это на Ideone!

Тестировать:

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

Сохранено 13 байтов благодаря Leaky Nun!

Спас Байт благодаря Денису!

медь
источник
def f(s)=на байт короче.
ThreeFx
2
@ThreeFx ты должен вернуться?
Утренняя монахиня
@ThreeFx Да, но тогда я должен написать return. lambdaВерсия 7 байт короче.
Медь
Вы правы. Сожалею.
ThreeFx
lambda s:[s[-1]]*s[-1]=s[-s[-1]:]
Утренняя монахиня
7

Pyth, 5 байт

gFer8

RLE на входе, возьмите последнюю пару и проверьте, больше или равно ли количество повторений, чем значение.

Попробуйте онлайн: демонстрация или тестовый набор

Jakube
источник
7

Желе , 5 байт

ŒgṪṫṪ

Входные данные - это массив кодовых точек, выходные данные - непустой массив (истинный) или пустой массив (ложный).

Попробуйте онлайн! или проверьте все контрольные примеры .

Как это работает

Œ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).
Деннис
источник
6

CJam, 9 8 байтов

Спасибо Sp3000 за сохранение 1 байта.

{e`W=:/}

Принимает целочисленный список как входные данные и возвращает 0(ложь) или положительное целое число (правда).

Тестирование.

объяснение

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.
Мартин Эндер
источник
6

05AB1E , 9 байтов

Для osabie нет кодировок длин серий :(

¤sR¬£¬QOQ

Объяснение:

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

С примером:

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

Использует кодировку CP-1252 . Попробуйте онлайн!

Аднан
источник
5

MATL , 10 байт

Спасибо @Adnan за замечание проблемы с более ранней версией кода

P0hG0):)&=

Когда вход имеет правильное заполнение, вывод представляет собой массив, содержащий только те, что является правдой . Когда он имеет неправильное заполнение, выводом является массив, содержащий по крайней мере ноль, и это также ложно .

Попробуйте онлайн! Или проверьте все тестовые случаи .

объяснение

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
Луис Мендо
источник
@ Аднан Работает сейчас
Луис Мендо,
Хорошо, выглядит хорошо :)
Аднан
2
Также поздравляю с 25к! : 3
Аднан
4

Mathematica, 29 байт

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

Разбейте входные данные на серии одинаковых элементов, извлеките последний и убедитесь, что его первый элемент меньше или равен длине этого цикла.

Мартин Эндер
источник
3

Haskell, 50 байтов

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

Принимает массив целых чисел в качестве входных данных.

ThreeFx
источник
Вам нужно импортировать Data.List, если вы не в REPL.
xnor
2

J, 13 байт

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

Принимает список в качестве единственного аргумента и выводит, 1если он верный и 0если ложный.

использование

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

объяснение

#~@{:-:{:{.|.  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
миль
источник
@randomra случай , такой как 3 4 3 3 3бы , ~.как 3 4так , чтобы последняя строка =находится 0 1 0 0 0. Я думаю, что работа с реверсом {:*/@{.0{=@|.должна работать, но в итоге получается также 13 байтов.
миль
Хорошо, хороший улов. Я пропустил это.
Рандомра
2

Brain-Flak , 54 байта

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

Входные данные представляют собой список целых чисел, выходные данные равны 1 для истинности и пустые для фальси.

объяснение

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

Цикл не заканчивается немедленно, когда встречается значение, которое приведет к возврату фальси. Вместо этого он переключается на другой стек, который пуст и проводит оставшиеся итерации, сравнивая 0 и 0.

0 '
источник
1
О, рад видеть тебя здесь! Добро пожаловать на сайт!
DJMcMayhem
1

Пакет, 101 байт

@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

Принимает входные данные в качестве параметров командной строки, циклически обходит их все, чтобы он мог получить последний n, циклически повторяет их все снова, чтобы подсчитать пробег конечных ns, и, наконец, вывести результат , 1если счетчик хотя бы равен n. В качестве альтернативы, если печать 0или ненулевое значение приемлемы, тогда для 93 байтов измените последнюю строку на @cmd/cset/ac/n.

Нил
источник
1

Haskell, 49 байтов

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

Попробуйте это на Ideone.

Укороченная версия, которая возвращает Trueправду и / Falseили исключение для фальсификации:

((==).head>>=all).(head>>=take).reverse
Laikoni
источник
1

Dyalog APL , 10 байт

(⊃∧.=⊃↑⊢)⌽

Является первым
∧.=все равно
первым
п , взятым из
в
обратном аргументе?

Попробуй APL онлайн!

Адам
источник
2
Сколько байт?
Конор О'Брайен
@ ConorO'Brien Извините, забыл заполнить шаблон.
Адам
1

Javascript (ES6), 51 47 41 байт

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

Примеры:

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
источник
1

C 91 байт

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

Ввод: указатель на массив с нулевым символом в конце.
Вывод: возвращает 0недопустимое заполнение и ненулевое значение допустимо (последний элемент в массиве)

Примеры:

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

дает:

3
2
0
0

Это зависит от неопределенного поведения. Если заполнение допустимо, оператора return нет, но использование gcc -std=c99этого возвращает последний элемент массива, который был передан (по крайней мере, на моем компьютере).

Райли
источник
1

Брахилог , 6 байт

a₁=.l∈

Попробуйте онлайн!

Выводится через предикат успеха или неудачи, как и в ответе Brachylog v1 от Leaky Nun. Использует аналогичный подход, но выходит намного короче.

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.

Брахилог , 6 байт

ḅt.l≥∈

Попробуйте онлайн!

Альтернативная версия, которая выходит той же длины, которая берет некоторое вдохновение от ответа Желе Денниса.

 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.
Несвязанная строка
источник
0

Сетчатка , 34 байта

Число байтов предполагает кодировку ISO 8859-1.

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

Input представляет собой список целых чисел, разделенных переводом строки. Отпечатки 0или 1.

Попробуйте онлайн! (Первая строка включает набор тестов, где в каждой строке есть один пробел.)

Альтернативная идея, которая заканчивается в 35 байтах и ​​печатает 0или положительное целое число:

.+
$*
\b(?=(1+)(¶\1)*$)(?<-2>1)*1\b
Мартин Эндер
источник
0

Javascript (ES5), 89 байт

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;
}
Пол Шмитц
источник
0

Brain-Flak 84 байта

100000000 бей меня здесь

Попробуйте онлайн!

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

Принимает ввод как массив целых чисел.

Объяснение впереди.

Вот 64-байтовая версия, которая выводит not of answer:

((({}))){({}[()]<(({})<([{}]{}<>)<>>)>)}<>([])({<{}>{}<([])>}{})
Мастер пшеницы
источник