# PKCS#7 padding validation

In cryptography, PKCS#7 padding is a padding scheme which adds a number of bytes N ≥ 1, where the value of each added byte is equal to N.

For example, Hello, World!, which has 13 bytes, is the following in hex:

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


If we choose to PKCS#7 pad to length 16, then the result is:

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


And if we choose to pad to length 20, then the result is:

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


Note that in the first example we add three 03 bytes, and in the second we add seven 07 bytes.

Your task will be to validate whether a string (or integer array) has correct PKCS#7 padding. That is, if the last byte of the input string is N, then your program should check that the last N bytes of the string are equal to N.

## Input

A single nonempty ASCII string containing characters between code points 1 and 127 inclusive. If you wish, you may take input as an array of integers instead.

## Output

A truthy value if the input string has valid PKCS#7 padding, otherwise a falsy value.

Both functions and full programs are acceptable. This is , so the aim is to minimise the number of bytes in your code.

## Test cases

The integer array version of inputs is presented here — the string version would have unprintable characters for many of the following test cases:

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]

• Is [1 2 3 3 3 3] truthy or falsey? I think it should be truthy but I'm not positive. – James Aug 27 '16 at 16:54
• @DJMcMayhem Truthy – Jakube Aug 27 '16 at 16:58
• @DJMcMayhem Truthy (this parallels the truthy test case ending in 7s). You can think of it as, after stripping, you'd end up with [1 2 3]. – Sp3000 Aug 27 '16 at 17:24
• Surely you meant to put a comma after Hello. (It's in the hex.) – rici Aug 28 '16 at 3:43
• @rici Thanks for noticing, fixed! – Sp3000 Aug 28 '16 at 3:50

# Python, 4734 33 bytes

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


s[-1] is the last member of the list s. Checks that the last s[-1] members of the input array s are the same as an array of s[-1] repeated that many times.

Takes input as an array of integers. This is a lambda expression; to use it, assign it by prefixing lambda with f=.

Try it on Ideone!

To test:

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


Saved 13 bytes thanks to Leaky Nun!

Saved a byte thanks to Dennis!

• def f(s)= is a byte shorter. – ThreeFx Aug 27 '16 at 15:45
• @ThreeFx you need to return? – Leaky Nun Aug 27 '16 at 15:46
• @ThreeFx Yes, but then I have to write return. The lambda version is 7 bytes shorter. – Copper Aug 27 '16 at 15:47
• You're right. Sorry. – ThreeFx Aug 27 '16 at 15:47
• lambda s:[s[-1]]*s[-1]=s[-s[-1]:] – Leaky Nun Aug 27 '16 at 15:48

# Brachylog, 14 bytes

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


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


# Pyth, 5 bytes

gFer8


RLE on input, take the last pair and check if the number of repeats is greater or equal than the value.

Try it online: Demonstration or Test Suite

# Jelly, 5 bytes

ŒgṪṫṪ


Input is an array of code points, output is a non-empty array (truthy) or an empty array (falsy).

### How it works

Œ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).


## CJam, 9 8 bytes

Thanks to Sp3000 for saving 1 byte.

{eW=:/}


Takes an integer list as input and returns 0 (falsy) or a positive integer (truthy).

Test suite.

### Explanation

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.


# 05AB1E, 9 bytes

No run-length encodings for osabie :(

¤sR¬£¬QOQ


Explanation:

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


With an example:

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


Uses the CP-1252 encoding. Try it online!

# MATL, 10 bytes

Thanks to @Adnan for noticing a problem with an earlier version of the code

P0hG0):)&=


When the input has correct padding, the output is an array containing only ones, which is truthy. When it has incorrect padding, the output is an array containing at least a zero, and so is falsy.

### Explanation

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 Working now – Luis Mendo Aug 27 '16 at 16:14
• Nice, looks good :) – Adnan Aug 27 '16 at 16:40
• Also, congratulations on 25k! :3 – Adnan Aug 27 '16 at 16:54

## Mathematica, 29 bytes

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


Split the input into runs of equal elements, extract the last, and check that its first element is less than or equal to the length of that run.

## Haskell, 50 bytes

import Data.List
((>=)<$>head<*>length).last.group  Takes an array of integers as input. • You need to import Data.List unless you're in the REPL. – xnor Aug 27 '16 at 18:32 # J, 13 bytes #~@{:-:{:{.|.  Takes the list as a single argument and outputs 1 if it is truthy and 0 if falsey. ## Usage  f =: #~@{:-:{:{.|. f 5 6 5 3 3 3 1 f 5 6 5 4 4 4 0  ## Explanation #~@{:-:{:{.|. 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 A case such as 3 4 3 3 3 would have ~. as 3 4 so that the last row of = is 0 1 0 0 0. I think operating on the reverse as {:*/@{.0{=@|. should work, but it ends up as 13 bytes also. – miles Aug 29 '16 at 11:38 • Right, nice catch. I missed that. – randomra Aug 29 '16 at 11:44 # Brain-Flak, 54 bytes (({})[()]){({}[()]<({}[({})]){<>}{}>)}{}{<>(<(())>)}{}  Input is a list of integers, output is 1 for truthy and empty for falsey. ## Explanation (({})[()]){ 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)  The loop does not immediately end when a value that would result in a falsey return is encountered. It is instead switched to the other stack which is empty and spends the rest of its iterations comparing 0 and 0. • Oh hey, nice to see you on here! Welcome to the site! – James Aug 28 '16 at 23:26 ## Batch, 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  Takes input as command-line parameters, loops over them all so that it can get the last one into n, loops over them all again to count the run of trailing ns, finally printing 1 if the count is at least equal to n. Alternatively if printing 0 or a non-zero value is acceptable, then for 93 bytes, change the last line to @cmd/cset/ac/n. # Haskell, 49 bytes f s|x<-(==last s)=x.length.fst.span x.reverse$s


Try it on Ideone.

Shorter version which returns True for truthy and False or an exception for falsy:

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


# Dyalog APL, 10 bytes

(⊃∧.=⊃↑⊢)⌽


⊃ Is the first
∧.= all-equal to
⊃ the first
↑ n taken from
⊢ the
⌽ reversed argument?

TryAPL online!

• How many bytes? – Conor O'Brien Aug 28 '16 at 3:32
• @ConorO'Brien Sorry, forgot to fill in the boilerplate. – Adám Aug 28 '16 at 8:11

## Javascript (ES6), 5147 41 bytes

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


Examples:

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

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


Input: a pointer to a null-terminated array.
Output: returns 0 for invalid padding and non-zero for valid (the last element in the array)

Examples:

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


Gives:

3
2
0
0


This does rely on undefined behavior. If the padding is valid there is no return statement, but using gcc -std=c99 this returns the last element of the array that was passed in (at least on my machine).

# Perl 5, 30 bytes

Includes +1 for -p

#!/usr/bin/perl -p
$_=/(.)\1*\z/s+length$&>ord$1  Try it online! # Brachylog, 6 bytes a₁=.l∈  Try it online! Outputs through predicate success or failure, as Leaky Nun's Brachylog v1 answer does. Takes a similar approach, as well, but comes out a lot shorter. 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≥∈  Try it online! An alternate version that comes out to the same length which takes some inspiration from Dennis' Jelly answer.  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.  # Retina, 34 bytes Byte count assumes ISO 8859-1 encoding. .+$*
\b(1(1)*)(?<-2>¶\1)*$(?(2)!)  Input is a linefeed-separated list of integers. Prints 0 or 1. Try it online! (The first line enables a test suite, where there is one space-separated test case per line.) An alternative idea that ends up at 35 bytes and prints 0 or a positive integer: .+$*
\b(?=(1+)(¶\1)*\$)(?<-2>1)*1\b


## Pyke, 7 bytes

eQ>}lt!


Try it here!

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


# Brain-Flak 84 bytes

100000000 beat me here

Try It Online!

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


Takes input as array of integers.

Explanation to come.

Here is a 64 byte version that outputs the not of the answer:

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