Pigpen-Verschlüsselung

11

Pigpen-Verschlüsselung

Ihre Mission ist einfach: Schreiben eines Programms, das Text als Eingabe empfängt und eine ASCII-Darstellung davon in der Pigpen-Chiffre ausgibt .

Eingang

Nur ASCII-Zeichen (kein Unicode). Sie müssen in der Lage sein, mindestens 16384 Zeichen und 256 Zeilen zu verarbeiten.

Ausgabe

  • Ersetzen Sie alle Zeichen, die keine neuen Zeilen oder in ABCDEFGHIJKLMNOPQRSTUVWXYZoder abcdefghijklmnopqrstuvwxyzdurch Leerzeichen sind.
  • Ersetzen Sie jeden Buchstaben ohne Berücksichtigung der Groß- und Kleinschreibung durch seine verschlüsselte Form (siehe nächster Abschnitt) und fügen Sie in jede der drei Zeilen nach jeder ein Leerzeichen ein. Jedes codierte Zeichen ist ein 3 * 3-Block von ASCII-Kunst. Ersetzen Sie Leerzeichen durch 3 * 3 Leerzeichenblöcke.
  • Alle Zeichen sollten sich in denselben drei Zeilen befinden (nennen Sie diese drei Zeilen eine Pigpen-Zeile), es sei denn, es gibt eine neue Zeile, die eine neue Pigpen-Zeile startet. Lassen Sie eine normale Linie zwischen den Schweinestalllinien leer.

Die Chiffre

  |       | |       |
 .|       |.|       |.
--+ for J +-+ for K +-- for L

--+       +-+       +--
 .|       |.|       |.
--+ for M +-+ for N +-- for O

--+       +-+       +--
 .|       |.|       |.
  | for P | | for Q |   for R

(ABCDEFGHI are the same as JKLMNOPQR, but with the . replaced by a space)

\./
 V  for W (note the row of 3 spaces on the top)

 ^
/.\ for Z (note the 3 spaces on the bottom)


 \
 .>
 /  for X (note the leading spaces)

 /
<.
 \  for Y (note extra trailing spaces)

(STUV are like WXYZ, but with the . replaced by a space)

Beispiel

Die Eingabe "hEllo, wORLd" sollte Folgendes erzeugen:

+-+ +-+ |   |   +--         +-- +-- |   --+
| | | | |.  |.  |.      \./ |.  |.  |.    |
| | +-+ +-- +-- +--      V  +-- |   +-- --+

Die base64-Codierung des obigen mit einer nachfolgenden neuen Zeile ist unten. Die md5sum ist 6f8ff1fed0cca4dd0492f9728ea02e7b.

Ky0rICstKyB8ICAgfCAgICstLSAgICAgICAgICstLSArLS0gfCAgIC0tKwp8IHwgfCB8IHwuICB8
LiAgfC4gICAgICBcLi8gfC4gIHwuICB8LiAgICB8CnwgfCArLSsgKy0tICstLSArLS0gICAgICBW
ICArLS0gfCAgICstLSAtLSsK

Ohne eine nachfolgende neue Zeile lautet die md5sum 581005bef7ee76e24c019d076d5b375fund die base64:

Ky0rICstKyB8ICAgfCAgICstLSAgICAgICAgICstLSArLS0gfCAgIC0tKwp8IHwgfCB8IHwuICB8

LiAgfC4gICAgICBcLi8gfC4gIHwuICB8LiAgICB8CnwgfCArLSsgKy0tICstLSArLS0gICAgICBW ICArLS0gfCAgICstLSAtLSs =

Regeln

  • Standardlücken sind verboten.
  • Das ist Code Golf. Der kürzeste Code gewinnt.
  • prompt()Verwenden Sie in Sprachen, die nicht mehrere Eingabezeilen gleichzeitig akzeptieren können (z. B. JavaScript mit ), *(oder ein anderes Zeichen) als Zeilentrennzeichen.

Erranda

  • Dem Beispiel fehlten einige Leerzeichen (Ein Leerzeichen sollte aus den nachfolgenden Leerzeichen des vorherigen Zeichens, falls vorhanden, selbst und seinen eigenen nachfolgenden Leerzeichen bestehen). Dies wurde nun behoben.

quelle
1
Ich erinnere mich, als Kind damit gespielt zu haben, wusste aber nie, wie es hieß. Vielen Dank!
Geobits
Kann ich eine benutzerdefinierte Schriftart verwenden? :-)
Florian F
@FlorianF No ...
Codierung in Javascript. Wird normalerweise promptfür die Eingabe verwendet, akzeptiert jedoch nur eine einzelne Zeile. Könnte ich ein spezielles Zeichen (wie '*') verwenden, um eine neue Zeile in der Eingabe zu markieren?
edc65
@ edc65 Ja, Sie können

Antworten:

4

JavaScript (ES6) 312 327 340 372 446

Ohne Leerzeichen und Zeilenumbrüche bei Einrückungen - könnte mehr Golf gespielt werden . Verwenden Sie ein '*', um neue Zeilen in der Eingabe zu markieren, da dies prompteine einzelne Zeile akzeptiert.

console.log(prompt().split('*').map(s=>
  [0,1,2].map(r=>
  [...s].map(c=>o+=n+
    '   \\1/ \\ /1\\ /  V  ^  1><1 --++-++-- 1||1||1 '.substr(
    (c=(32|c.charCodeAt())-97)<0|c>25?0:c<18
     ?27+3*'330441552030141252033144255'[f=8,c%9*3+r]
     :3*'482630015274'[f=21,c%4*3+r],3,n=' ')
  .replace(1,' .'[r&c>f])
  ,n='\n'),o=''
)&&o).join('\n'))

Test in der FireFox / FireBug-Konsole

Eingabe: ABCDEFGHI * JKLMNOPQR * STUV * WXYZ * HeLlO WoRlD!

  | | | |   --+ +-+ +-- --+ +-+ +--
  | | | |     | | | |     | | | |  
--+ +-+ +-- --+ +-+ +--   | | | |  

  | | | |   --+ +-+ +-- --+ +-+ +--
 .| |.| |.   .| |.| |.   .| |.| |. 
--+ +-+ +-- --+ +-+ +--   | | | |  

     \   /   ^ 
\ /   > <   / \
 V   /   \     

     \   /   ^ 
\./  .> <.  /.\
 V   /   \     

+-+ +-+ |   |   +--         +-- +-- |   --+    
| | | | |.  |.  |.      \./ |.  |.  |.    |    
| | +-+ +-- +-- +--      V  +-- |   +-- --+      
edc65
quelle
Sie haben 5 Leerzeichen zwischen ound win "Hallo Welt", das OP hat nur 4
Claudiu
@Claudiu jedes Zeichen (auch leer, Zeichen 32) 3 Leerzeichen, Trennzeichen zwischen Zeichen 1 Leerzeichen. 1 + 3 + 1 == 5. Ich werde mit OP
edc65
Ja, mit 5 macht es definitiv mehr Sinn. Ich dachte, er wollte speziell 4 als Sonderfall, aber gut, dass Sie gefragt haben!
Claudiu
3

C # - 921 720

Offensichtlich kein Gewinnerbeitrag, aber das sah nach zu viel Spaß aus, um es weiterzugeben :)

Das Programm nimmt die Eingabe einzeln auf und druckt dann den Schweinestall. Verwenden Sie zur Eingabe mehrerer Zeilen einen Unterstrich (_), wie in der Ausgabe dargestellt .

Code

using System;class P{static void Main(){
int i,y,j,k,w,z;string[]g=Console.ReadLine().ToLower().Split('_');
var d="_________  |b .|b--+_| |b|.|b+-+_|  b|. b+--_--+b .|b--+_+-+b|.|b+-+_+--b|. b+--_--+b .|b  |_+-+b|.|b| |_+--b|. b|  _____   b\\./b v _ \\ b .>b / _ / b<. b \\ _ ^ b/.\\b   _  b  b  ".Replace('b','\n').Split('_');
for(i=0;i<d.Length;i++){if(d[i]==""){d[i]=i<17?d[i+9]:d[i+4];d[i]=d[i].Replace('.',' ');}}
for(y=0;y<g.Length;y++){string o="",s,e=g[y];var r=new string[z=e.Length][];
for(i=0;i<z;i++){if(e[i]-97<0|e[i]-97>25)e=e.Replace(e[i],'{');
o+=d[e[i]-97]+'_';r[i]=(o.Split('_')[i].Split('\n'));}
for(j=0;j<3;j++)for(k=0;k<(w=r.Length);k++){
s=r[k][j];Console.Write(k==w-1?s+'\n':s+' ');}}
Console.ReadLine();}}

Konzept

Die Chiffre verwendet einige Zeichenfolgen, die ziemlich oft dupliziert werden. Zum Beispiel wird '-' 16 Mal angezeigt und '__' (zwei Leerzeichen) wird 20 Mal angezeigt. Ich ersetze diese Sequenzen durch Einzelzeichensymbole und schalte sie zur Laufzeit aus, wobei ich die Anzahl der Zeichen, die zum Speichern der Pigpen-Chiffre erforderlich sind, halbiere. Ebenso erfordert eine neue Zeile normalerweise zwei Zeichen, wird jedoch durch ein Symbol (n) ersetzt und später ausgeschaltet.

Das Programm verarbeitet mehrere Eingabezeilen, indem es die Eingabe in ein Array aufteilt, in dem jedes Element eine einzelne Eingabezeile ist. Das Programm führt dann einfach die Verschlüsselung in jeder Zeile separat aus.

Dies ist mein erstes Golfspiel in einer beliebigen Sprache, daher kann wahrscheinlich viel getan werden, um diesen Code zu verbessern.

Ausgabe

hEllo,wORLd
+-+ +-+ |   |   +--        +-- +-- |   --+
| | | | |.  |.  |.     \./ |.  |.  |.    |
| | +-+ +-- +-- +--     v  +-- |   +-- --+

code_golf
|   +-- --+ +-+
|   |.    | | |
+-- +-- --+ +-+
--+ +-- |   +--
  | |.  |.  |
  | +-- +-- +--

multi_line_input
--+  /  |    \  +--
 .| <   |.    > |
--+  \  +--  /  |
|   +-- +-+ +-+
|.  |   |.| | |
+-- |   +-+ +-+
+-- +-+ --+  /   \
|   |.|  .| <     >
|   +-+   |  \   /
jrbuchner
quelle
1
Ich kenne C # nicht, aber es scheint einen unnötigen Platz in for(int i=0;i<p.Length; i++)(nahe der Mitte) zu geben
Danke Professorfish, es gab noch einen, den ich ebenfalls vermisst habe
jrbuchner
1
In m♥lti \n lin♣e \n inputmeinem Telefon wird dies so dargestellt, dass es ein Herz anstelle von u in multi und einen Club zwischen n und e in der Linie hat. Warum das?
Beta Decay
2
@BetaDecay Ich denke, es ist beabsichtigt, den Umgang mit niedrigen ASCII-Zeichen zu zeigen
edc65
Das Herz und der Verein wurden dort platziert, um die Einhaltung der Herausforderungsregel zu demonstrieren: Ersetzen Sie alle Zeichen, die keine neuen Zeilen sind, oder in ABCDEFGHIJKLMNOPQRSTUVWXYZ oder abcdefghijklmnopqrstuvwxyz durch Leerzeichen
jrbuchner
2

Python 2, 180 + 78 + 1 + 3 = 262 Zeichen

Das 180-Byte-Programm (die letzten beiden Zeilenumbrüche sind Registerkarten):

L=open('f','rb').read().decode('zip')
while 1:
 n=raw_input()
 for s in(0,3,6):
    for c in n:w=ord(c.lower())-97;print''.join(L[w+(s+i)*26]for i in(0,1,2))if-1<w<27 else'  ',
    print

Erfordert, dass eine 78-Byte-Datei mit dem Namen 'f' dasselbe Verzeichnis ist (+1 Byte für Dateinamen), das Folgendes enthält:

$ hexdump f
0000000 9c78 a853 d1a9 d6d5 2206 3805 0103 c174
0000010 c100 8b88 07d1 9ae1 051a 4ab0 385d ae03
0000020 2803 8a82 3a80 406c ae18 0f42 6006 0c1c
0000030 0a2d 31fa 6076 ee8c a030 0e14 2987 8428
0000040 7501 3080 c39a 5a10 0014 21c7 7333
000004e

Die base64-Codierung der Datei flautet:

eJxTqKnR1dYGIgU4AwF0wQDBiIvRB+GaGgWwSl04A64DKIKKgDpsQBiuQg8GYBwMLQr6MXZgjO4w
oBQOhykohAF1gDCawxBaFADHITNz

Das Programm wird mit einer Ausnahme beendet und 2>_unterdrückt den Fehler (+3 Byte):

$ echo "hEllo,wORLd" | python pigpen.py 2>_| ./md5.py
7ed49b7013a30cc3e84aa807f6585325

Erklärung :

Ich habe eine Nachschlagetabelle erstellt L, bei der es sich um eine Zuordnung handelt {position_in_3x3_block: {letter_being_encrypted: symbol_for_letter_at_position}}, die in einem flachen Array gespeichert ist. Das Programm druckt die Buchstaben, indem es für jede Position eine einfache Suche durchführt.

Claudiu
quelle
Sie sollten ein Byte für fund drei Bytes für2>_
0

Perl 5 -lF , 297 288 261 231 Bytes

$,=$";$_=' .||.||. ';chomp@F;map{@r=/.../g;say map{/[a-z]/i?$r[-65+ord uc]:$"x3}@F}(y/./ /r.y/.| /-+-/r x2)x2 .'    \\  /  ^ 'x2,y/./ /r x3 .$_ x3 .'\\ /  ><  / \\\\./ .><. /.\\',(y/.| /-+-/r x2 .y/./ /r)x2 .' V  /  \\    'x2;say''

Probieren Sie es online aus!

Es gibt hier wahrscheinlich noch ein bisschen, das weiter golfen könnte.

Xcali
quelle