Перевірка прокладки PKCS № 7


25

У криптографії PKCS # 7 padding - це схема прокладки, яка додає кількість байтів 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]

Фальсі:

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

Це [1 2 3 3 3 3]truthy чи falsey? Я думаю, що це повинно бути правдою, але я не позитивний.
DJMcMayhem

@DJMcMayhem Truthy
Jakube

@DJMcMayhem Truthy (це паралельний тестовий випадок truthy, який закінчується на 7s). Ви можете подумати про це, як після зняття, ви закінчилися [1 2 3].
Sp3000

Звичайно, ви мали намір поставити козу після Hello. (Це в шістнадцять.)
rici

@rici Дякую за зауваження, виправлено!
Sp3000

Відповіді:


8

Пітон, 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 вам потрібно повернутися?
Leaky Nun

@ThreeFx Так, але тоді мені доведеться писати return. lambdaВерсія 7 байт коротше.
Мідь

Ти правий. Вибачте.
ThreeFx

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



7

Желе , 5 байт

ŒgṪṫṪ

Введення - це масив кодових точок, вихід - не порожній масив (truthy) або порожній масив (Falsy).

Спробуйте в Інтернеті! або перевірити всі тестові випадки .

Як це працює

Œ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(фальшивий) або додатне ціле число (truthy).

Тестовий набір.

Пояснення

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

@Adnan Робота зараз
Луїс Мендо

Приємно, добре виглядає :)
Аднан

2
Також вітаємо з 25к! : 3
Аднан

4

Математика, 29 байт

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

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


3

Haskell, 50 байт

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

Приймає масив цілих чисел як вхідний.


Вам потрібно імпортувати 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 байтами.
миль

Правильно, приємний улов. Я пропустив це.
randomra

2

Мозок-Флак , 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.


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

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


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

Це залежить від невизначеної поведінки. Якщо прокладка дійсна, немає повернення заяви, але використанняgcc -std=c99 це повертає останній елемент масиву, який був переданий (принаймні, на моїй машині).



1

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

a₁=.l∈

Спробуйте в Інтернеті!

Виходи через предикат успіху чи невдачі, як це робить відповідь Braaklog 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)!)

Введення - це список цілих чисел, відокремлений рядковими колами. Друкує 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};

Безголівки:

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

Мозок-Флак 84 байти

Тут мене побили 100000000

Спробуйте в Інтернеті!

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

Вводиться як масив цілих чисел.

Пояснення про майбутнє.

Ось 64-байтна версія, яка видає не відповідь:

((({}))){({}[()]<(({})<([{}]{}<>)<>>)>)}<>([])({<{}>{}<([])>}{})
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.