PKCS#7パディング検証


25

暗号化では、PKCS#7パディングは、N≥1のバイト数を追加するパディング方式で、追加される各バイトの値はNに等しくなります。

たとえば、Hello, World!13バイトの16進数は次のとおりです。

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

長さ16にPKCS#7パッドを選択すると、結果は次のようになります。

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

最初の例では3 03バイトを追加し、2番目の例では7 07バイトを追加します。

あなたの仕事は、文字列(または整数配列)に正しいPKCS#7パディングがあるかどうかを検証することです。つまり、入力文字列の最後のバイトがNである場合、プログラムは文字列の最後のNバイトがNに等しいことを確認する必要があります。

入力

コードポイント1〜127の間の文字を含む単一の空でないASCII文字列。必要に応じて、代わりに整数の配列として入力を受け取ることができます。

出力

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]truthyまたはfalseyは?私それが真実であるべきだと思うが、私は前向きではない。
DJMcMayhem

@DJMcMayhem Truthy
ジャクベ

@DJMcMayhem Truthy(これは7sで終わる真実のテストケースに相当します)。あなたは、それを剥ぎ取った後、あなたがで終わると考えることができます[1 2 3]
Sp3000

きっと、Helloの後にコンマを入れるつもりでした。(それはヘックスにあります。)
リチ

@rici気づいてくれてありがとう、修正しました!
Sp3000

回答:


8

Python、47 34 33バイト

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

s[-1]はリストの最後のメンバーですss[-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

Leaky Nunのおかげで13バイト節約されました!

デニスのおかげでバイトを節約できました!


def f(s)=1バイト短いです。
ThreeFx

2
@ThreeFx返品する必要がありますか?
リーキー修道女

@ThreeFxはい、しかし、私はを書かなければなりませんreturnlambdaバージョンは、7バイト短いです。

あなたが正しい。ごめんなさい。
ThreeFx

lambda s:[s[-1]]*s[-1]=s[-s[-1]:]
リーキー修道女



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バイト

1バイトを節約してくれたSp3000に感謝します。

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

入力に正しいパディングがある場合、出力は1のみを含む配列になります。これはtruthyです。パディングが正しくない場合、出力は少なくともゼロを含む配列であるため、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 Working now
ルイスメンドー

ニース、よさそうだ:)
アドナン

2
また、25kおめでとうございます!:3-
アドナン

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バイトにもなってしまう。
マイル

いいね。私は逃しました。
ランダラ

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)

falseyを返す値に遭遇した場合、ループはすぐに終了しません。代わりに、空で他のスタックに切り替えられ、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にループします。最後のループをもう一度ループして、後続nのsの実行をカウントし、最後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

これは未定義の動作に依存します。パディングが有効な場合、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)!)

入力は、改行で区切られた整数のリストです。印刷0または1

オンラインでお試しください!(最初の行は、1行に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;
}

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.