Playfair 암호화 프로그램 작성


20

Playfair 암호화 기술에 따라 두 줄을 입력하고 첫 번째를 핵심 문구로 사용하여 두 번째를 암호화하는 프로그램을 작성하십시오.

Wikipedia는 Playfair 암호화에 대해 자세히 설명 하지만 모호성을 피하기 위해 간단한 요약을 제공합니다.

1. 키 테이블을 생성하십시오.

J키워드 의 모든 어커런스를 I로 바꾸고 알파벳이 아닌 문자와 반복되는 문자를 모두 제거하십시오. 5x5 암호화 테이블에 삽입하여 나머지 셀을 나머지 알파벳으로 채 웁니다 (단 J, 우리는 싫어합니다 J).

예:

                                        S T A C K
                                        O V E R F
Stack Overflow  -->  STACKOVERFLW  -->  L W B D G
                                        H I M N P
                                        Q U X Y Z

2. 암호화 할 메시지 준비

모든 교체 JI을 사용하여 쌍으로 모든 비 알파벳 문자와 분할을 제거, X두 번 같은 문자를 포함하는 모든 쌍을 중단 할 수 있습니다. 홀수 개의 문자로 X끝나는 경우 끝에 추가 하십시오. (참고 : - 숫자는 전체 철자되어야한다 ONE, TWO, THREE, 등 -하지만 당신이 이미 당신을 위해 수행 된 가정 할 수 있습니다.)

예:

In:
The cat crept into the crypt, crapped, and crept out again.

Out:
TH EC AT CR EP TI NT OT HE CR YP TC RA PX PE DA ND CR EP TO UT AG AI NX

3. 암호화

각 문자 쌍을 차례로 암호화하십시오. 이들이 키 테이블의 다른 행과 열에있는 경우, 각 문자를 다른 문자가있는 열에서 동일한 행의 문자로 바꾸십시오 (예 : VMEI, LZGQ). 동일한 행 (또는 열)에있는 경우 필요에 따라 줄 바꿈하여 오른쪽 (또는 아래)에 즉시 두 문자를 선택하십시오 (예 : OEVR, ZGKP).

예:

In:
TH EC AT CR EP TI NT OT HE CR YP TC RA PX PE DA ND CR EP TO UT AG AI NX

Out:
SI RA CA RD FM VU IC VS MO RD ZN AK EC MZ MF BC YN RD FM SV TV KB TM MY

이 프로세스에서 생성 된 문자열은 프로그램에서 출력해야하는 암호화 된 메시지입니다.

규칙 :

  • 입력 텍스트 및 키는 stdin, 명령 줄 인수 또는 기타 이러한 소스 에서 얻을 수 있습니다 . 하드 코딩 된 입력은 허용되지 않습니다.
  • 프로그램은 암호 문구와 메시지에 대해 대문자와 소문자를 모두 허용해야합니다.
  • 암호화 된 출력은 대문자 또는 소문자 일 수 있습니다.
  • 프로그램은 64 자 이상의 키 구문과 16KB 이상의 메시지 텍스트를 허용해야합니다.
  • 비 ASCII 입력을 처리 할 필요는 없습니다.
  • XX암호화 중에 문자 쌍이 발생할 가능성을 무시할 수 있습니다 .
  • 프로그램 출력에 공백을 추가 할 필요가 없습니다.
  • 답은 메시지, 핵심 문구 및 프로그램에서 생성 된 암호화 된 출력의 예를 포함해야합니다.
  • 이것은 코드 골프 도전이므로 가장 짧은 코드 (바이트)의 답이 이길 것입니다.

참고 : 연속 된 문자 가 동일한 쌍으로 표시 되는 경우에만 연속 문자를 분리해야합니다 . 예를 들어 , 이중 은 분할되어야하지만 이중 은 MASSACHUSETTS암호화 되지 않아야합니다.MA SX SA CH US ET TSST


8
"우리는 싫어 J" "APL에 대해 비슷한 감정을 품고 있습니까?
algorithmshark

고 블디 구크! (그 이름에 J가 없다는 것은 가치가 있지만, 나는 생각한다.)
ossifrage ossifrage

입력 요구 사항과 관련하여 함수 인수가 허용됩니까? (이것이 "하드 코딩"을 구성하는지 확실하지 않은 경우) 그렇지 않은 경우 키에 줄 바꿈이없는 것으로 가정 할 수 있습니까 (바람직하게는 일반 텍스트도)? 그렇지 않은 경우 명령 행 인수가 stdin에 비해 더 실행 가능할 수 있습니다.
AlliedEnvy

답변:


13

JI는 * 536 431 417 380 263 218 203 197 186 167

p=:4 :0
a=.u:65+9-.~i.26
,_2(5|,:~@|.@(=/)+$$,A.~5*1-0{=/)&.(5 5#:(~.n x,a)&i.)\(,'X'#~2|#)(({.,'X',}.)~1+2*1{&I._2{.\2=/\]) ::]^:_(n=:a(e.~#])'JI'charsub toupper)y
)

(@algorithmshark의 광범위한 제안과 함께)

사용 예 :

   'Stack Overflow' p 'The cat crept into the crypt, crapped, and crept out again.'
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

입력을 올바르게 분할합니다 :

   d=:(({.,'X',}.)~1+2*1{&I._2{.\2=/\]) ::]
   d^:_ 'MASSACHUSETTS'
MASXSACHUSETTS

* 모든 교체 JI오른쪽?


2
우리는 J를 좋아하지 않지만 나는 아름답습니다!
Vereos

와, 이건 특별하다.
squeamish ossifrage

첫 번째 버전이보고있는 동안 조금 나에게 마법 등을이 최신의 순수한 부두입니다. 매우 인상적인 감소.
Geobits

키 팝이 떨어지는 것을보고 팝 팝 팝! 이 부두 술 마법의 작동 방식에 대한 설명을 원하는 사람은 다음과 같습니다 . 심한 경련이 없으면 답변에 맞추기가 너무 깁니다.
algorithmshark

나는 지금 J를 좋아한다 :-)
squeamish ossifrage

7

루비 461 개 411 366 359 352 346 330 문자

k,m=$<.map{|x|x.tr(?j,?i).upcase.tr('^A-Z','').chars}
t=[*((k&k)|[*?A..?Z]-[?J]).each_slice(5)]
m=(m*'').gsub(/(.)\1/,'\1X\1').chars
c=->n{[t.index{|r|k=r.index n},k]}
$><<(m.size%2<1?m:m+[?X]).each_slice(2).map{|p,q|a,b,d,e=*c[p],*c[q]
a==d ?[t[a][(b+1)%5],t[d][(e+1)%5]]:b==e ?[t[(a+1)%5][b],t[(d+1)%5][e]]:[t[a][e],t[d][b]]}*''

저장에 대한 @daniero 덕분에 ... err, 많은 바이트. \영형/

ungolfed 코드는 다음과 같습니다.

key = gets.chomp
msg = gets.chomp
transform = ->str{
    str.gsub! 'j', 'i'
    str.upcase!
    str.gsub! /[^A-Z]/, ''
    str.split('')
}

# 1. Generate a key table
key = transform[key]
chars = key.uniq + ([*?A..?Z] - key - ['J'])
tbl = Array.new(5) {
    Array.new(5) {
        chars.shift
    }
}

# 2. Prepare the message
msg = transform[msg]
msg = msg.join('').gsub(/(.)\1/){ "#{$1}X#{$1}" }.split('')
msg = (msg.length % 2 == 0 ? msg : msg + ['X']).each_slice(2).to_a

# 3. Encryption
coords = ->chr{
    i = -1
    [tbl.index{|row| i = row.index chr}, i]
}
msg.map! do |c1, c2|
    c1, c2 = coords[c1], coords[c2]
    if c1[0] == c2[0]
        # same row
        [tbl[c1[0]][(c1[1] + 1) % 5], tbl[c2[0]][(c2[1] + 1) % 5]]
    elsif c1[1] == c2[1]
        # same column
        [tbl[(c1[0] + 1) % 5][c1[1]], tbl[(c2[0] + 1) % 5][c2[1]]]
    else
        # neither
        [tbl[c1[0]][c2[1]], tbl[c2[0]][c1[1]]]
    end
end

# Output!
puts msg.join

다음은 몇 가지 샘플 출력입니다.

llama@llama:...code/ruby/ppcg23276playfair$ printf 'Stack Overflow\nThe cat crept into the crypt, crapped, and crept out again.\n' | ./playfair.rb; printf 'This is a password!\nProgramming Puzzles and Code Golf is a Stack Exchange site.\n' | ./playfair.rb
SIRAVXRDFMVUUYVSBLRDZNYVECMZMFBCYNRDFMSVTVKBVBMY
WDDEDSXIXOQFBTUYVQFISQWGRPFBWMESATAHHGMBVEITQFFISHMI

외모에 좋은,하지만 개선의 여지가있다 : 첫 번째 줄에 "캐스트"할 필요가 없습니다 chars배열로 당신은 또한 당신이 사용할 수있는 루비 2를 사용하는 가정, &집합 연산자로 대신 tr: t=->s{s.gsub(?j,?i).upcase.chars&[*?A..?Z]}(7 바이트 저장). 다음 두 줄은 k,m=[1,2].map{t[gets.chop]}( chop대신에 노트) 와 결합 될 수 있습니다 chomp.
daniero jan

&또한 사용하면 uniq나중에 필요하지 않습니다 . 그리고 charsto to 배열은 6 번 라인에도 적용됩니다.
daniero

@daniero 맞아요, 이것은 꽤 오래 전에 이루어 졌으므로 아마도 더 많은 개선이 이루어질 것입니다. 팁 주셔서 감사합니다. 이것을 다시 방문 할 시간!
Doorknob

그래, 나는 그것을 본다 :) 나는 도전에 걸려 넘어졌고 나는 당신의 대답을 볼 때까지 루비에서 그것을 찌르기를 원했습니다. 코드의 복잡성 때문에 그것을 두려워했습니다. 그것 좀 봐 :)
daniero

@daniero 불행하게도, tr&라인 1은하지 않습니다에 대한 작업 때문에 m할 수 없다 uniq는 ified. 그러나 (1 바이트) k.uniq로 단축 할 수 있습니다 (k&k).
Doorknob

4

C : 495 개 401 355 341 문자

지금은 대략적인 스케치입니다. 최소한 백 글자를 깎을 수 있어야합니다.

목표 달성 : 100 개 이상의 캐릭터 (현재 154 개)가 코드에서 신비하게 사라졌습니다.

p[25],l[96],a=1,b,c;o(x,y){putchar(p[x%5^y%5?x/5*5+(x/5^y/5?y:x+1)%5:(x+5)%25]);}main(){for(;a&&((a=(b=getchar())>31)||(b=65))||b++<90;c=0)for(b&=-33;b/65-b/91&&p[c]^b-(b==74);p[c++]||(p[--c]=b-(b==74),l[b]=c));for(;b=getchar(),b=b>31?b&-33:(c=88),b=b/65-b/91?a?a^b?(c*=c==88,b):(c=b,88):(a=b,0):0,a&b&&(o(a=l[a],b=l[b]),o(b,a),a=c),c^88;);}

유쾌한 공백이 있습니다.

p[25],l[96],a=1,b,c;
o(x,y){
    putchar(p[
        x%5^y%5
            ?x/5*5+(x/5^y/5?y:x+1)%5
            :(x+5)%25
    ]);
}
main(){
    for(;
        a&&(
            (a=(b=getchar())>31)||
            (b=65)
        )||b++<90;
        c=0
    )for(
        b&=-33;
        b/65-b/91&&
        p[c]^b-(b==74);
        p[c++]||(
            p[--c]=b-(b==74),
            l[b]=c
        )
    );
    for(;
        b=getchar(),
        b=b>31
            ?b&-33
            :(c=88),
        b=b/65-b/91
            ?a
                ?a^b
                    ?(c*=c==88,b)
                    :(c=b,88)
                :(a=b,0)
            :0,
        a&b&&(
            o(a=l[a],b=l[b]),
            o(b,a),
            a=c
        ),
        c^88;
    );
}

나는 잠들기 직전에 프로그램의 첫 번째 반복을 썼기 때문에 불필요한 의미없는 진술 등이 많이있었습니다. 그것의 대부분은 수정되었지만 개선이 가장 확실하게 가능한 영역은 꽤 있습니다.


1
글쎄, 이것은 내 노력을 매우 나쁘게 보이게합니다! 당신이 이것으로 얼마나 멀리 갈 수 있을지 기대합니다 :-)
squeamish ossifrage

2

MATLAB-458 자

function p=pf(k,p)
k=[upper(k),65:90];k(k==74)=73;k(k<65|k>90)='';[~,i]=unique(k,'first');k=reshape(k(sort(i)),5,5);e=[k,k(:,1);k(1,:)];p=upper(p);p(p==74)=73;p(p<65|p>90)='';n=length(p);for i=1:2:n
if i<n&&p(i)==p(i+1)p=[p(1:i),88,p(i+1:end)];end
n=length(p);end
if mod(n,2)p=[p,88];n=n+1;end
for i=1:2:n [x,y]=find(k==p(i));[w,z]=find(k==p(i+1));p(i:i+1)=[k(w,y),k(x,z)];if x==w p(i:i+1)=[e(w,y+1),e(x,z+1)];end
if y==z p(i:i+1)=[e(x+1,z),e(w+1,y)];end
end

몇 가지 예 :

octave:180> pf('Stack Overflow', 'The cat crept into the crypt, crapped, and crept out again.')
ans = SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

octave:181> pf('This is a password!','Programming Puzzles and Code Golf is a Stack Exchange site.')
ans = WDDEDSXIXOQFBTUYVQFISQWGRPFBWMESATAHHGMBVEITQFFISHMI

octave:182> pf('Matlab needs lambdas', 'Who thought elseif is good syntax?')
ans = XGQMFQPKQDSACDKGRIFPQNILDMTW

2

하스켈-711

데모:

[timwolla@/data/workspace/haskell/PCG]ghc pcg-23276.hs
[1 of 1] Compiling Main             ( pcg-23276.hs, pcg-23276.o )
Linking pcg-23276 ...
[timwolla@/data/workspace/haskell/PCG]./pcg-23276 "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

암호:

import Data.List
import Data.Char
import Data.Maybe
import System.Environment
main=do a<-getArgs
    putStrLn$concat$map(x (a!!0))$map(\x->if (length x)==1 then x++"X"else x)$s 2$concat$map(\x->if (length x)==1then x else intersperse 'X' x)$group$p (a!!1)
p=map(\x->if x=='J' then 'I' else x).filter(isUpper).map toUpper
k x=y++(delete 'J'$['A'..'Z']\\y)where y=nub$p x
u l m=(div i 5,mod i 5)where i=fromJust$elemIndex l$k m
x y z
    |a/=c&&b/=d=(e!!(a*5+d)):(e!!(c*5+b)):[]
    |a==c=(e!!(a*5+(mod(b+1)5))):(e!!(c*5+(mod(d+1)5))):[]
    |True=(e!!((5*(mod(a+1)5))+b)):(e!!((5*(mod(c+1)5))+d)):[]
    where
        o=u(z!!0)y
        t=u(z!!1)y
        a=fst o
        b=snd o
        c=fst t
        d=snd t
        e=k y
s _ []=[]
s n l=(take n l):(s n(drop n l))

큰 버전 :

import Data.List
import Data.Char
import Data.Maybe

encryptAll key text = map (encrypt key) (transformValue text)

clean x = map (\x -> if x == 'J' then 'I' else x) $ filter (isUpper) $ map (toUpper) x
transformKey x = y ++ (delete 'J' $ ['A'..'Z'] \\ y)
    where y = nub (clean x)

transformValue x = map (\x -> if (length x) == 1 then x ++ "X" else x) $ split 2 $ concat $ map (\x -> if (length x) == 1 then x else intersperse 'X' x) $ group $ clean x

search letter key = (div index 5, mod index 5)
    where index = fromJust $ elemIndex letter $ transformKey key

encrypt key chars
    | rowA /= rowB && colA /= colB = (key' !! (rowA * 5 + colB)) : (key' !! (rowB * 5 + colA)) : []
    | rowA == rowB = (key' !! (rowA * 5 + ((colA + 1) `mod` 5))) : (key' !! (rowB * 5 + ((colB + 1) `mod` 5))) : []
    | otherwise = (key' !! ((5 * ((rowA + 1) `mod` 5)) + colA)) : (key' !! ((5 * ((rowB + 1) `mod` 5)) + colB)) : []
    where
        rowA = fst $ search (head chars) key
        colA = snd $ search (head chars) key
        rowB = fst $ search (last chars) key
        colB = snd $ search (last chars) key
        key' = transformKey key

-- http://stackoverflow.com/a/12876438/782822
split :: Int -> [a] -> [[a]]
split _ [] = []
split n l
  | n > 0 = (take n l) : (split n (drop n l))
  | otherwise = error "Negative n"

2

피스-111

경쟁하기에 너무 늦었을뿐입니다. 인코더디코더 다음과 같습니다.

L@G:rb0\j\iJ{y+wGKywWhZ=Zh*2xlR{RcK2 1IhZ=KXZK\x;M@J+G?!eH5?!hH?q4%G5_4 1eHVcK2A,xJhNxJeN=Z-V.DH5.DG5pgGZpgH_RZ

설명:

L    b                              L defines common method y(b); 2 calls helps us saving two bytes
    r 0                             lowercase r(b,0)
   :   \j\i                         : replaces all occurrences of "j" with "i"
 @G                                 strips all non-alphabetic characters; G = pyth built-in alphabet

    w                               first input argument
   + G                              appends the alphabet (G)
  y                                 calls y(b)
 {                                  { makes set (removes duplicated characters)
J                                   assigns result to 'J' (KEY VARIABLE)

Kyw                                 assigns output from y(second input argument) to 'K' (TEXT VARIABLE)

WhZ                         ;       While (Z+1 != 0) <-> While (Z != -1) <-> While mismatched items found
             cK2                    list of K pairs.                    e.g. 'ABCCDDE' -> [AB, CC, DD, E]
         lR{R                       l length of { unique characters.    e.g. [2, 1, 1, 1]
        x       1                   1-length first index.               e.g. 1
     h*2                            *2+1 (Index in K)                   e.g. 3 'ABC CDDE'
   =Z                               Assigns to 'Z'
                  IhZ               if (Z != -1) <-> if (mismatched found)
                     =KXZK\x        X Inserts at Z index in K an 'x' and reassigns to 'K'  e.g. 'ABCXC...'

M                                   M defines function g(G, H) where G index H vector (INDEX CONVERSION)
     ?!eH                           if (same col)
         5                              then +5
         ?!hH                           else { if (same row)
             ?q4%G5                             then if (last col)
                   _4                               then -4
                      1                             else +1
                       eH                       else col
   +G                               index += increment
 @J                                 J[index]

VcK2                                V loops over cK2 list of K pairs
     ,xJhNxJeN                      x returns pair members index in J
    A                               A assigns G = xJhN, H = xJeN
                  .DH5              .D returns [row, col] = [i/5,i%5] of 5xn matrix from index of H
                      .DG5          idem. of G
                -V                  Subtracts vectors (RELATIVE POSITION)
              =Z                    Assigns to 'Z'
                          pgGZ          p prints g(G, Z) return value
                              pgH_RZ    p prints g(H, _RZ) return value, and _R changes signs of Z vector

샘플 키 / 메시지 / 출력 :

Stack Overflow
Gottfried Leibniz is famous for his slogan Calculemus, which means Let us calculate. He envisioned a formal language to reduce reasoning to calculation.
lfaukvvnrbbomwpmupkoexvqkovfimaqohflcmkcdsqwbxqtlintinbehcbovttksbtybsavmormwuthrhrbkevfxebqbspdxtbfsvfrwyarfrctrhmpwkrssbtybsvurh

1

C, 516

가독성 향상을 위해 줄 바꿈이 추가되었습니다 . (적합성이 창 밖으로 나왔는데 걱정입니다.)

#define Z(u,v) putchar(o[u]),putchar(o[v])
#define X while((Y=getchar())>31){Y&=223;if(Y==74)Y--;if(Y<65||Y>90
P,L,A,Y,f,a,i,r,c=512,o[25],d[2],*e=o;Q(){for(i=0;o[i]!=d[0];i++);i-=(f=i%5);
for(r=0;o[r]!=d[1];r++);r-=(a=r%5);if(f==a)Z(f+(i+5)%25,a+(r+5)%25);
else if(i==r)Z((f+1)%5+i,(a+1)%5+r);else Z(a+i,f+r);}main(){X||c&(A=1<<Y-65))continue;
c|=A;*e++=Y;}A=1;Y=65;for(P=0;P<25;P++){if(!(c&A))*e++=Y;
if(++Y==74)Y++,A+=A;A+=A;}L=0;X)continue;if(L&&Y==*d)d[1]=88,Q(),*d=Y;
else d[L]=Y,L=1-L;if(!L)Q();}if(L)d[1]=88,Q();}

예:

$ ./pf
Playfair                                    
The quick brown fox jumps over the lazy dog
QMHNPEKSCBQVTPSVEPEFTQUGDOKGAYXFRTKV

1

파이썬 3 709 705 685 664

stdin의 입력을 승인합니다.

from string import ascii_uppercase as a
from itertools import product as d
import re
n=range
k=input()
p=input()
t=lambda x: x.upper().replace('J','I')
s=[]
for _ in t(k+a):
 if _ not in s and _ in a:
  s.append(_)
m=[s[i:i+5] for i in n(0,len(s),5)]
e={r[i]+r[j]:r[(i+1)%5]+r[(j+1)%5] for r in m for i,j in d(n(5),repeat=2) if i!=j}
e.update({c[i]+c[j]:c[(i+1)%5]+c[(j+1)%5] for c in zip(*m) for i,j in d(n(5),repeat=2) if i!=j})
e.update({m[i1][j1]+m[i2][j2]:m[i1][j2]+m[i2][j1] for i1,j1,i2,j2 in d(n(5),repeat=4) if i1!=i2 and j1!=j2})
l=re.findall(r'(.)(?:(?!\1)(.))?',''.join([_ for _ in t(p) if _ in a]))
print(''.join(e[a+(b if b else 'X')] for a,b in l))

예:

mfukar@oxygen[/tmp]<>$ python playfair.py
Stack Overflow
The cat crept into the crypt, crapped, and crept out again.
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

또한 파이썬 2.5에서도 완벽하게 작동합니다 :-)
squeamish ossifrage

1

파이썬 : 591 바이트

import sys
l=list
n=len
a=[sys.stdin.readline().upper().replace('J','I') for i in (1,2)]
b=l('ABCDEFGHIKLMNOPQRSTUVWXYZ')
def z(x):
    a=0
    if x in b:
        b.remove(x)
        a=1
    return a
c=l(filter(z,a[0]))+b
d=[x for x in a[1] if x in c]
e=1
while e<n(d):
    if d[e-1]==d[e]:
        d.insert(e,'X')
    e+=2
if n(d)%2>0:
    d+='X'
def y(i):
    z=c.index(d[i])
    return z/5,z%5
x=lambda i,j:c[(i%5)*5+(j%5)]
def w(i):
    e,f=y(i)
    g,h=y(i+1)
    if e==g:
        z=x(e,f+1)+x(g,h+1)
    elif f==h:
        z=x(e+1,f)+x(g+1,h)
    else:
        z=x(e,h)+x(g,f)
    print z,
e=0
while e<n(d):
    w(e)
    e+=2
print

이것은 사용 stdin순서대로 키와 메시지를받을 수 있습니다. 플랫 매트릭스를 사용하여 암호화 매트릭스를 저장하는 것을 부정하지 않기를 바랍니다. 매트릭스로 작업하는 것이 매우 간단했기 때문입니다. 다음은 몇 가지 예제 실행입니다.

>python playfair.py
Stack Overflow
The cat crept into the crypt, crapped, and crept out again.
SI RA CA RD FM VU IC VS MO RD ZN AK EC MZ MF BC YN RD FM SV TV KB TM MY

>python playfair.py
Stack Overflow
The quick red fox jumps over the lazy brown dog.
SI OX TU KS FR GR EQ UT NH OL ER VC MO BS QZ DE VL YN FL

나는 당신이 단축 될 수 있습니다 생각 zlambda x:0if b not in x else b.remove(x)or 1. 또한 제거 할 수있는 많은 공백이 있습니다. 또한 filter외부에서 정의하는 대신 호출 로 직접 이동할 수 있습니다 .
Morgan Thrapp

1

자바-791

내 첫 골프, 그래서 어떤 비판도 환영합니다. 내가해서는 안되기 때문에 Java를 사용합니다. 그렇게 나쁘지 않은데; 현재 리더의 두 배보다 작은 크기. Java 이기 때문에 더 커질 것으로 기대했습니다. :)

public class P{static String c(String s){return s.toUpperCase().replace('J','I').replaceAll("[^A-Z]","");}static int f(char[]a, char n){for(int i=0;i<a.length;i++)if(a[i]==n)return i;return -1;}public static void main(String[]a){int i=0,k,l;char j=0;String g=c(a[0]);char[]e,b,h=c(a[1]).toCharArray();b=new char[25];for(;j<g.length();j++)if(j==g.indexOf(g.charAt(j)))b[i++]=g.charAt(j);for(j=65;i<25;j++)if(f(b,j)<0&&j!=74)b[i++]=j;e=new char[h.length*2];for(i=0,j=0;j<h.length;){if(i%2>0&&h[j]==h[j-1])e[i++]=88;e[i++]=h[j++];}if(i%2>0)e[i++]=88;for(j=0;j<i;j+=2){k=f(b,e[j]);l=f(b,e[j+1]);if(k/5==l/5){e[j]=b[(k/5*5)+((k+1)%5)];e[j+1]=b[(l/5*5)+((l+1)%5)];}else if(k%5==l%5){e[j]=b[(k+5)%25];e[j+1]=b[(l+5)%25];}else{e[j]=b[(k/5*5)+(l%5)];e[j+1]=b[(l/5*5)+(k%5)];}}System.out.println(e);}}

자동 형식으로 :

public class P {
    static String c(String s) {
        return s.toUpperCase().replace('J', 'I').replaceAll("[^A-Z]", "");
    }

    static int f(char[] a, char n) {
        for (int i = 0; i < a.length; i++)
            if (a[i] == n)
                return i;
        return -1;
    }

    public static void main(String[] a) {
        int i = 0, k, l;
        char j = 0;
        String g = c(a[0]);
        char[] e, b, h = c(a[1]).toCharArray();
        b = new char[25];
        for (; j < g.length(); j++)
            if (j == g.indexOf(g.charAt(j)))
                b[i++] = g.charAt(j);
        for (j = 65; i < 25; j++)
            if (f(b, j) < 0 && j != 74)
                b[i++] = j;
        e = new char[h.length * 2];
        for (i = 0, j = 0; j < h.length;) {
            if (i % 2 > 0 && h[j] == h[j - 1])
                e[i++] = 88;
            e[i++] = h[j++];
        }
        if (i % 2 > 0)
            e[i++] = 88;
        for (j = 0; j < i; j += 2) {
            k = f(b, e[j]);
            l = f(b, e[j + 1]);
            if (k / 5 == l / 5) {
                e[j] = b[(k / 5 * 5) + ((k + 1) % 5)];
                e[j + 1] = b[(l / 5 * 5) + ((l + 1) % 5)];
            } else if (k % 5 == l % 5) {
                e[j] = b[(k + 5) % 25];
                e[j + 1] = b[(l + 5) % 25];
            } else {
                e[j] = b[(k / 5 * 5) + (l % 5)];
                e[j + 1] = b[(l / 5 * 5) + (k % 5)];
            }
        }
        System.out.println(e);
    }
}

샘플 출력 :

>java P "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

>java P "Write a PlayFair encryption program" "Write a program that takes two lines of input and uses the first as a key phrase to encrypt the second according to the Playfair encryption technique."
RITEWFCPGMWPGEBLYTWYQTXWINOLMWVNLECAXRNBURZWXWQILEWUWYWNQTFLDINWWEMICOTPYRIKWZRMGCBPGUOGPUWOKYGIQILYPFAPTIWMDPFLETGCEWODOWDZTZ

1

JS (노드) - 528 466

k=n(2)+'ABCDEFGHIKLMNOPQRSTUVWXYZ',p=n(3),t=o=''
for(i=0;i<k.length;i++)if(!~t.indexOf(k[i]))t+=k[i]
for(i=0;i<p.length;){a=f(c=p[i++]),b=f(!(d=p[i])||c==d?'X':(i++,d))
if(a.x==b.x)a.y=(a.y+1)%5,b.y=(b.y+1)%5
else if(a.y==b.y)a.x=(a.x+1)%5,b.x=(b.x+1)%5
else a.x=b.x+(b.x=a.x,0)
o+=t[a.x+a.y*5]+t[b.x+b.y*5]}console.log(o)
function f(c){x=t.indexOf(c);return{x:x%5,y:x/5|0}}
function n(a){return process.argv[a].toUpperCase().replace(/[^A-Z]/g,'').replace(/J/g,'I')}

샘플 출력 :

$ node playfair "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY
$ node playfair "Lorem ipsum" "dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."
CRORSDAHGAMQKPXDOFQMQAMSBSSPUPBPTDMOAHURNRCRLUAULRGNMLCPLSKDSBSBSQQAHMIGRERYMQCROREMAGDTSZIMUHAIAQRQALSGLAHSLZRQPIETAPDXRPNMSFRYMEBPZGHARKIEMIOGROIGREPUHSUPAQIMUHAPUOYRPGRLLRCRKPXDUYAINZ

정규식 문제에 대한 좋은 점 — 질문에 대한 메모를하겠습니다
ossifrage

두 번째 예에 문제가 있습니다. 문자 75 및 76의 문자 쌍은로 인코딩됩니다 UU. 반복 E해야 할 부분이 반복 된 것 같습니다 .
squeamish ossifrage

네 말이 맞아, 나는 발로 나를 쐈다. 문제는 쌍을보고 있지만 삽입 후 하나씩 끝나는 것입니다.
zobier

1

PHP 582

<? list($i,$k,$v)=array_map(function($v){return str_split(preg_replace('#[^A-Z]#','',strtr(strtoupper($v),'J','I')));},$argv);@$i=array_flip;$k=$i($k)+$i(range('A','Z'));unset($k['J']);$k=array_keys($k);$q=$i($k);for($i=1;$i<count($v);$i+=2){if ($v[$i-1]==$v[$i]){array_splice($v,$i,0,'X');}}if(count($v)%2)$v[]='X';for($i=1;$i<count($v);$i+=2){$c=(int)($q[$v[$i-1]]/5);$d=$q[$v[$i-1]]%5;$e=(int)($q[$v[$i]]/5);$f=$q[$v[$i]]%5;if($c==$e){$d=($d+1)%5;$f=($f+1)%5;}elseif($d==$f){$c=($c+1)%5;$e=($e+1)%5;}else{$t=$f;$f=$d;$d=$t;}$v[$i-1]=$k[$c*5+$d];$v[$i]=$k[$e*5+$f];}echo join($v);

Ungolfed
Decoder

출력

$ php playfair.php "Stack Overflow" "The cat crept into the crypt, crapper, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFECYNRDFMSVTVKBTMMY
$ php playfair.php "This was codegolf?" "The full J answers is shorter than my preparation code :("
HIOKVGFHCMWTKZWSIYWIEPWAMWTCPNXQZKMOMEHSCPODEA

1

펄, 265

매우 간단합니다.

chomp(($k,$_)=map{uc=~y/A-Z//cdr=~y/J/I/r}<>."@{[A..Z]}",~~<>);1while$k=~s/((.).*)\2/$1/;while(/(.)((?=\1|$)|(.))/g){($a,$b,$c,$d)=map{$e=index$k,$_;5*int$e/5,$e%5}$1,$3||X;print substr$k,$_%25,1 for$a-$c?$b-$d?($a+$d,$c+$b):($a+5+$b,$c+5+$d):(++$b%5+$a,++$d%5+$c)}

들여 쓰기 :

chomp(($k,$_)=map{uc=~y/A-Z//cdr=~y/J/I/r}<>."@{[A..Z]}",~~<>);
1while$k=~s/((.).*)\2/$1/;
while(/(.)((?=\1|$)|(.))/g){
    ($a,$b,$c,$d)=map{$e=index$k,$_;5*int$e/5,$e%5}$1,$3||X;
    print substr$k,$_%25,1 for
        $a-$c
            ?$b-$d
                ?($a+$d,$c+$b)
                :($a+5+$b,$c+5+$d)
            :(++$b%5+$a,++$d%5+$c)
}

0

CoffeeScript-610

데모:

[timwolla@/data/workspace/js/PCG]coffee pcg-23276.coffee "Stack Overflow" "The cat crept into the crypt, crapped, and crept out again."
SIRACARDFMVUICVSMORDZNAKECMZMFBCYNRDFMSVTVKBTMMY

암호:

String::r=String::replace
_=(t,l)->
    for r in[0..4]
        for c in[0..4]
            return [r,c]if l is t[r][c]
K = {}
K[c]=c for c in (process.argv[2].toUpperCase().r(/J/g, 'I').r x=/([^A-Z])/g, '')
for i in[1..26]when i!=10
    c=String.fromCharCode 64+i
    K[c]=c
K=(c for c of K)
t=(K[s..s+4]for s in[0..24]by 5)
v=process.argv[3].toUpperCase().r(/J/g,'I').r(x,'').r(/(.)\1/g,'$1X$1').r /(..)/g, '$1 '
o=""
for p in v.trim().r(/\s([A-Z])$/, ' $1X').split /\s/
    [a,b]=p.split '';[d,f]=_ t,a;[e,g]=_ t,b
    o+=if d!=e&&f!=g
        t[d][g]+t[e][f]
    else if d==e
        t[d][++f%5]+t[e][++g%5]
    else
        t[++d%5][f]+t[++e%5][g]
console.log o

언 골프 버전 :

search = (table, letter) ->
    for row in [0..4]
        for column in [0..4]
            return [ row, column ] if letter is table[row][column]

encrypt = (key, value) ->
    key = key.toUpperCase().replace(/J/g, 'I').replace /([^A-Z])/g, ''
    keyChars = {}
    keyChars[char] = char for char in key
    for i in [1..26] when i != 10
        char=String.fromCharCode 64 + i
        keyChars[char] = char
    keyChars = (char for char of keyChars)

    keyTable = (keyChars[start..start+4] for start in [0..24] by 5)

    value = value.toUpperCase().replace(/J/g, 'I').replace(/([^A-Z])/g, '').replace(/(.)\1/g, '$1X$1').replace /(..)/g, '$1 '
    pairs = value.trim().replace(/\s([A-Z])$/, ' $1X').split /\s/

    out = ""
    for pair in pairs
        [a,b] = pair.split ''
        [rowA, colA] = search keyTable, a
        [rowB, colB] = search keyTable, b
        if rowA!=rowB&&colA!=colB
            out += keyTable[rowA][colB]+keyTable[rowB][colA]
        else if rowA==rowB
            out += keyTable[rowA][++colA%5]+keyTable[rowB][++colB%5]
        else
            out += keyTable[++rowA%5][colA]+keyTable[++rowB%5][colB]
    out.replace /(..)/g, '$1 '

console.log encrypt process.argv[2], process.argv[3]
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.