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(含1和127)之间的字符。如果愿意,可以将输入作为整数数组代替。

输出量

truthy值,如果输入字符串具有有效的PKCS#7填充,否则falsy值。

功能和完整程序都可以接受。这是,所以目的是最大程度地减少代码中的字节数。

测试用例

此处显示输入的整数数组版本-对于以下许多测试用例,字符串版本将具有不可打印的字符:

真相:

[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]真还是假?我认为这应该是真实的,但我并不乐观。
DJMcMayhem

@DJMcMayhem Truthy
Jakube '16

@DJMcMayhem Truthy(这与以7s 结尾的真实测试用例平行)。您可以将其视为剥离后的结果[1 2 3]
Sp3000

您当然想在Hello之后加上逗号。(以十六进制表示。)
rici

@rici感谢您注意,已修复!
Sp3000

Answers:


8

Python,47 34 33字节

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

s[-1]是列表的最后一个成员s。检查s[-1]输入数组的最后一个成员ss[-1]重复多次的数组相同。

将输入作为整数数组。这是一个lambda表达式;要使用它,请在前面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

感谢Leaky Nun节省了13个字节!

感谢Dennis,节省了一个字节!


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

Brachylog,14个字节

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

在线尝试!

~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

7

Pyth,5个字节

gFer8

在输入上进行RLE,获取最后一对,并检查重复次数是否大于或等于该值。

在线尝试:演示测试套件


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):)&=

当输入具有正确的填充时,输出是仅包含一个的数组,这是true。如果填充不正确,则输出是一个至少包含零的数组,因此也是falsy

在线尝试!验证所有测试用例

说明

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现在工作
路易斯·门多,

不错,看起来不错:)
Adnan

2
另外,恭喜25k!:3
Adnan

4

Mathematica,29个字节

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

将输入拆分为相等元素的游程,提取最后一个元素,并检查其第一个元素小于或等于该游程的长度。


3

Haskell,50个字节

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

将整数数组作为输入。


除非您在REPL中,否则需要导入Data.List。
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

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。


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上尝试。

简短版本返回Truetrue False或falsy例外:

((==).head>>=all).(head>>=take).reverse


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

这确实依赖于未定义的行为。如果填充有效,则没有return语句,但是使用gcc -std=c99此语句返回传入的数组的最后一个元素(至少在我的机器上)。



1

Brachylog,6个字节

a₁=.l∈

在线尝试!

通过谓词成功或失败进行输出,就像Leaky Nun的Brachylog v1答案一样。也采用类似的方法,但结果要短得多。

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个字节

ḅ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)!)

输入是一个由换行符分隔的整数列表。打印01

在线尝试!(第一行启用一个测试套件,其中每行有一个用空格分隔的测试用例。)

一个以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

Brain-Flak 84字节

1亿在这里打败我

在线尝试!

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

将输入作为整数数组。

解释来了。

这是一个64字节的版本,输出的不是答案:

((({}))){({}[()]<(({})<([{}]{}<>)<>>)>)}<>([])({<{}>{}<([])>}{})
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.