Implementieren Sie diese Schlüsselverschlüsselung


13

Implementieren Sie diese Schlüsselverschlüsselung

Tor

Verwenden Sie den im Abschnitt Algorithmus erläuterten Algorithmus, um eine bestimmte Verschlüsselung zu implementieren.

Das Programm muss Eingaben von STDIN oder dem nächstgelegenen verfügbaren Äquivalent lesen und den Algorithmus verwenden, um den Chiffretext und einen Schlüssel zu generieren.

Der Chiffretext und der Schlüssel werden in STDOUT oder das nächste verfügbare Äquivalent geschrieben. Jedes Format ist zulässig, solange es den Chiffretext und den Schlüssel ausgibt.

Algorithmus

Konvertieren Sie die Zeichen in der Zeichenfolge in die entsprechenden ASCII-Werte. Beispielsweise:

Hello -> 72 101 108 108 111

Als Nächstes müssen Sie einen Schlüssel generieren, solange die Zeichenfolge Zufallszahlen im Bereich von 0 bis 9 enthält.

Hello -> 62841

Fügen Sie die Ganzzahlen in der Zufallszahlenfolge zu den ASCII-Werten der Zeichenfolge hinzu. In den obigen Beispielen würde 72 zu 78 und 101 zu 104 werden.

72 + 6 = 78, 101 + 2 = 103, 108 + 8 = 116, etc

Als nächstes konvertieren Sie die neuen Werte zurück in Zeichen. In den obigen Beispielen ist der Text Hellogeworden Ngtpp.

Beispiele

(Dies sind lediglich Beispiele dafür, wie die Ausgabe aussehen könnte . Die Ausgabe kann und wird variieren.)

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

Regeln

  • Sie können davon ausgehen, dass die Eingabe nur Zeichen im Bereich von az, AZ und Leerzeichen enthält.
  • Einsendungen müssen vollständige Programme oder Funktionen sein.
  • Einsendungen werden in Bytes gewertet.
  • Standardlücken sind verboten.
  • Das ist Code-Golf, also gewinnt der kürzeste Code.

(Dies ist eine meiner ersten Herausforderungen. Wenn etwas nicht stimmt, können Sie mir gerne mitteilen, wie ich es verbessern kann.)


5
Diese Herausforderung sieht für mich gut aus, abgesehen von ein paar Gedanken. 1. Ist eine Funktion anstelle eines vollständigen Programms zulässig? Eine verwandte Frage ist, ob die Werte zurückgegeben und nicht gedruckt werden können. 2. Sie sagten, preferably with the format (ciphertext)\n(key)."Bevorzugte Features" und Code-Golf passen nicht gut zusammen. Sie sollten dies verbindlich festlegen oder andere Ausgabeformate zulassen. 3. Muss der Schlüssel ohne Leerzeichen gedruckt werden? Was ist mit dem Drucken im Listenformat, zB [0, 5, 2, ...]?
DJMcMayhem

Kann der Schlüssel führende Nullen haben?
TheBikingViking

1
Schöne erste Herausforderung, aber ich bin mir bei den strengen IO-Formaten nicht so sicher. In der Regel sind Funktionen zulässig und Antworten können von einer der akzeptierten E / A-Methoden gelesen werden. Dazu gehört die Ausgabe eines Arrays mit den Elementen
Downgoat

1
Müssen die Ziffern des Schlüssels mit einer gleichmäßigen Verteilung generiert werden?
Dennis

1
Äh ... 101 + 2 ist 103, nicht 104. :-)
YetiCGN

Antworten:


5

Gelee , 12 9 Bytes

⁵ṁX€’Ṅ+OỌ

Probieren Sie es online!

Wie es funktioniert

⁵ṁX€’Ṅ+OỌ  Main link. Argument: s (string)

⁵             Set the return value to 10.
 ṁ            Mold; create an array of 10's with the length of s.
  X€          Pseudo-randomly pick a integer between 1 and 10, for each 10.
    ’         Decrement, so the integers fall in the range [0, ..., 9].
     Ṅ        Print the key, as an array, followed by a linefeed.
      +O      Add the integers to the ordinals (code points) of s.
        Ọ     Unordinal; convert back to characters.

5

Python 3, 130 Bytes

Vielen Dank an @Rod für den Hinweis auf einen Fehler

from random import*
def f(x):l=10**len(x);k=str(randint(0,l-1)+l)[1:];print(''.join(chr(ord(i)+int(j))for i,j in zip(x,k))+'\n'+k)

Eine Funktion, die Eingaben über Argumente als Zeichenfolge akzeptiert und an STDOUT ausgibt.

Wie es funktioniert

from random import*  Import everything from the random module
def f(x):            Function with input string x
l=10**len(x)         Define l for later use as 10^length(x)
randint(0,l-1)+l     Generate a random integer in the range [0, l-1] and add l, giving a
                     number with l+1 digits...
k=str(...)[1:]       ...convert to a string and remove the first character, giving a key of
                     length l that can include leading zeroes, and store in k
for i,j in zip(x,k)  For each character pair i,j in x and k:
chr(ord(i)+int(j))    Find the UTF-8 code-point (same as ASCII for the ASCII characters),
                      add the relevant key digit and convert back to character
''.join(...)         Concatenate the characters of the ciphertext
print(...+'\n'+k)    Add newline and key, then print to STDOUT

Probieren Sie es auf Ideone


Ihr Schlüsselgenerator generiert keine Schlüssel, die mit 0 beginnen. Das Erhöhen der Grenzen um den Faktor 10 und das Entfernen der ersten Ziffer sollte Abhilfe schaffen: m=10**len(x);k=str(randint(m,m*10))[1:];und Sie speichern sogar ein Byte in dem Prozess. c:
Rod

@ Rod Danke für den Hinweis auf den Fehler. Das spart jedoch keine Bytes, da randintes inklusive ist, was bedeutet, dass Sie dies tun müssten m*10-1. Ich habe mir gerade eine Möglichkeit ausgedacht, dies für die gleiche Byteanzahl zu beheben.
TheBikingViking

3

Pyth - 16 Bytes

Warten auf die Entscheidung von OP über die Ausgabeformate.

sCM+VCMQKmOTQjkK

Test Suite .


Ich habe mich für das Format entschieden.
m654

3

Eigentlich 17 Bytes

;`X9J`M;(O¥♂cΣ@εj

Probieren Sie es online!

Erläuterung:

;`X9J`M;(O¥♂cΣ@εj
;                  dupe input
 `X9J`M            for each character in input copy:
  X9J                discard the character, push a random integer in [0, 9]
       ;           duplicate the offset array
        (O         bring input to top of stack, ordinal array
          ¥♂c      pairwise addition with offset array, turn each ordinal into a character
             Σ     concatenate
              @εj  concatenate the copy of the offset array


2

MATL, 13 Bytes

"10r*]v!kGy+c

Die Ausgabe sieht folgendermaßen aus:

9 5 8 2 1
Qjtnp

Probieren Sie es online!

Erläuterung:

"    ]          % For each character:
 10             % Push a 10 onto the stack
   r            % Push a random float in [O, 1)
    *           % Multiply. This essentially the same thing as pushing a number in [0, 10)
      v!k       % Join all of these together, and take the floor
         G      % Push the input again
          y     % Duplicate the array of random numbers
           +    % And add these together. Since MATL treats strings as an array of chars, we don't need to explicitly convert types
            c   % Display as string

Ich bin nicht sicher, ob das das richtige Format ist ...
Undichte Nonne

@Leaky Nun, ich habe die Regeln ein wenig geändert.
m654

@ m654 Wo hast du gesagt, dass es zwischen den Werten Leerzeichen geben kann?
Undichte Nonne

@LeakyNun Ursprünglich gab es eine Regel gegen sie, aber ich habe sie entfernt.
m654

1
Gute Idee, die Schleife zu benutzen. Es ist tatsächlich kürzer als die Version mit mehreren Eingängen von roderYr
Luis Mendo

2

PowerShell v2 +, 79.77 Byte

param($n)-join(($x=[char[]]$n|%{0..9|Random})|%{[char]($_+$n[$i++])});-join$x

Übernimmt die Eingabe $n, durchläuft jedes Zeichen und erhält Randombei 0..9jeder Iteration ein Element . Speichert diese Zahlen (als Array) in $x. Leitet dieses Array in eine andere Schleife. Jede Iteration nimmt das aktuelle Element $_, fügt es dem in Scheiben geschnittenen Positionszeichen hinzu $n(implizite Umwandlung von Zeichen in Ganzzahl) und wandelt es dann um als [char]. Lässt das in der Pipeline. Das ist in Parens eingekapselt und -joinzusammengefügt, um das Wort zu bilden. Das ist noch in der Pipeline. Zusätzlich wird die Nummer $xauch -joinzusammengefügt und in der Pipeline belassen. Diese werden implizit mit einem Write-Outputam Ende der Ausführung gedruckt, was dazu führt, dass sie standardmäßig mit einer neuen Zeile gedruckt werden.

Beispiel

PS C:\Tools\Scripts\golfing> .\implement-this-key-cipher.ps1 'Hello World!'
Lhoot(Yt{mf"
433358259121

2

C #, 252 247 245 232 216 Bytes

Die Größe ist ziemlich schlecht im Vergleich zu den anderen Lösungen, aber trotzdem ...

using System;using System.Linq;class p{static void Main(){var c="";var i=Console.ReadLine();var r=new Random();for(int b=0;b++<i.Count();){int d=r.Next(10);Console.Write((char)(i[b]+d));c+=d;}Console.Write("\n"+c);}}

Dies ist meine zweite Antwort auf einen Codegolf und ich bin ein ziemlicher Anfänger in Anbetracht von C #, also würde ich gerne hören, wie ich es kürzer machen kann :)

Ungolfed:

using System;
using System.Linq;

class p
{
    static void Main()
    {
        var c = "";
        var i = Console.ReadLine();
        var r = new Random();
        for (int b = 0; b++ < i.Count();)
        {
            int d = r.Next(10);
            Console.Write((char)(i[b] + d));
            c += d;
        }
        Console.Write("\n" + c);
    }
}
  • 5 Bytes dank @FryAmTheEggman eingespart
  • 2 Bytes gespart dank @theLambGoat
  • Gespeichert 7 Bytes durch Entfernen staticaus der Klasse p
  • 24 Bytes gespart dank @milk

1
Der Trick ist, nicht mit anderen Sprachen zu vergleichen;) Ich bin nicht besonders gut mit C # -Golf vertraut, aber können Sie b++<i.Count()den dritten Satz auch leer lassen? Auch ich glaube nicht , dass Sie ein Newline benötigen, so der letzte Aufruf WriteLinekönnte Writestatt.
FryAmTheEggman

Ich bin auch nicht gut mit C # vertraut, aber ich denke, Sie können das = r.Next (10) bis zur Deklaration von d verschieben und eine Reihe von Klammern beim Schreiben speichern. Oder gibt der Zufall kein int zurück, so dass Sie das nicht tun können?
theLambGoat

Ich denke, ich kann das tun, lass mich nachsehen
Tom Doodler

Sie können Typen durch ersetzen var. dh- var c=anstatt string c=ein paar Bytes zu rasieren.
Milch

Warum lassen Sie das Ergebnis nicht Console.ReadLine()als String? i.Lengthist kürzer als i.Count(), System.Linq wird nicht benötigt. string hat einen char indexer. Auch die Schaffung neue zufällig ausgewählte Objekte in der Schleife weniger Bytes: new Random().Next(10).
Milch

2

CJam, 11 Bytes

Nq{Amr_o+}/

Probieren Sie es online!

Wie es funktioniert

N            Push a linefeed on the stack.
 q           Read all input from STDIN and push it on the stack.
  {      }/  For each character in the input:
   Amr       Pseudo-randomly pick an integer in [0 ... 9].
      _o     Print a copy.
        +    Add the integer to the character.
             (implicit) Print the linefeed, followed by the modified characters.

2

05AB1E , 18 17 Bytes

vžh.RDyÇ+ç`?}J¶?,

Erläuterung

v           }      # for each char in input
 žh.RD             # push 2 copies of a random number in [0..9]
      yÇ+          # add 1 copy to the current chars ascii value
         ç`?       # convert to char, flatten and print
             J     # join stack (which contain the digits of the key)
              ¶?,  # print a newline followed by the key

Probieren Sie es online aus


2

Python 3, 112 Bytes

c ist eine Funktion, die den verschlüsselten Text und den Schlüssel zurückgibt

from random import*
c=lambda t:map(''.join,zip(*[(chr(a+b),str(b))for a,b in((ord(i),randint(0,9))for i in t)]))

Hier ist ein Code, der das Gleiche tut und etwas besser lesbar ist

def encrypt(text):
    # keep the codes of the letters in the input and a random key
    # that will be used later to encrypt this letter
    letter_and_key = ((ord(letter),randint(0,9)) for letter in text)

    # encrypt the letter and keep the key used as a string
    output_and_key = [(chr(letter_code+key), str(key))
                      for letter_code, key in letter_and_key]

    # At this point the values are kept in the format:
    # [(firstletter, firstkey), (secondletter, secondkey), ...]

    # to reorder the list to be able to output in the format "text key"
    text, key = map(''.join, zip(*output_and_key))

    # same as print(*output_and_key)
    return text, key

Ausgabe:

>>> text, key = c('Hello World')
>>> print(text, key, sep='\n')
Liuot#`oylk
44935390707

Willkommen auf dieser Seite!
DJMcMayhem

1

PHP, 63 86 82 Bytes

Bearbeiten: vergessen, den Schlüssel zu drucken ...

Vielen Dank an Alex Howansky, der mir 4 Bytes gespart hat.

for(;$i<strlen($a=$argv[1]);$s.=$r)echo chr(ord($a[$i++])+$r=rand(0,9));echo"
$s";

Die Eingabe erfolgt über ein Befehlszeilenargument. Nimmt jedes Zeichen in der Zeichenfolge und fügt seinem ASCII-Code ein zufälliges int von 0 bis 9 hinzu. Anschließend wird der Code wieder in ASCII konvertiert. Jede Zufallszahl wird angehängt$s , die am Ende gedruckt wird.


Sie müssen auch den Schlüssel ausdrucken.
Alex Howansky

Sie können das $s.=$rnach dem 2. Semi in die for-Schleife einfügen und ein Byte speichern, da Sie das nachfolgende Semi ausgeben können. Dann besteht Ihre Schleife nur noch aus einer Anweisung, sodass Sie die Umbruchklammern ausschneiden und 2 weitere Bytes einsparen können. Am Ende können Sie den $sin Anführungszeichen gesetzten String einfügen und den .Operator um ein weiteres Byte speichern. :)
Alex Howansky

@ AlexHowansky: Das ist sehr wahr. Vielen Dank
Business Cat

1

J, 32 Bytes

<@:e,:~[:<[:u:3&u:+e=.[:?[:$&10#

Python-Äquivalent:

from random import randint
def encrypt(message):
    rand_list = list(map(lambda x: randint(0, 9), range(len(message))))
    return (''.join(list(map(lambda x,y: chr(x+y), rand_list, map(ord, message)))), rand_list)

1

Perl, 34 Bytes

Beinhaltet +1 für -p

#!/usr/bin/perl -p
s%.%$\.=$==rand 10;chr$=+ord$&%eg

0

Perl, 65 Bytes

for(split'',$ARGV[0]){$;.=$a=int rand 9;$b.=chr$a+ord}say"$b\n$;"

Ich habe eine Weile gebraucht, um herauszufinden, wie ich die Eingabe am Ende ohne neue Zeile erhalten kann. Nimmt es als Kommandozeilenargument


Ihre Lösung hat einige Probleme. Die Eingabe wird nicht von STDIN gelesen, $;startet nicht leer, druckt also den alten Inhalt und der Rand kann niemals 9 generieren. Sie sind einfach zu reparieren und die Verwendung von STDIN wird Ihren Code kürzer machen :-)
Ton Hospel

@TonHospel Normalerweise sind die Eingabevoraussetzungen locker und Argumente gegenüber STDIN akzeptabel. Während die Eingabe über STDIN kürzer ist, wird sie durch Entfernen des Zeilenumbruchs länger. Und während rand Zahlen <9 generiert, sollte Perls int-Methode eher Runden als Floors sein, sodass alles> = 8.5 als 9
enden

Die Eingabeanforderungen sind normalerweise locker, aber hier war es nicht. Nicht Newline von STDIN zu bekommen ist einfach: <>=~/./g. Und nein, intin Perl schneidet es gegen 0 ab, es rundet nicht. perl -wle 'print int 8.6'Ausgänge8
Ton Hospel

0

Python 2, 84 99 Bytes

def f(x):y=`id(x)**len(x)`[1:len(x)+1];return''.join(map(chr,[ord(a)+int(b)for a,b in zip(x,y)])),y

Verwendet den id()Wert der Zeichenfolge, um Zufallszahlen zu generieren.

Versuch es


Sie müssen den Schlüssel sowie den Chiffretext ausgeben.
TheBikingViking

@TheBikingViking weiß nicht, wie ich das verpasst habe. Thanks - fixed
atlasologist

Ich denke, dass dies auch das gleiche Problem hat wie eine frühere Version meiner Python-Antwort; Es werden niemals Schlüssel mit führenden Nullen erzeugt.
TheBikingViking

@TheBikingViking Wieder
behoben

wechseln map(chr,[ord(a)+int(b)for a,b in zip(x,y)])zu map(lambda x,y:chr(ord(x)+int(y)),x,y)? das sollte etwas retten
ljeabmreosn

0

Senva , 74 Bytes

Hier ist das kürzeste Programm, das ich gemacht habe:

2'(`>0.>{@}0'{v}2-2'0,{@}1'{v}0'{+}{'}9%+{^}{1-}1'"{+}{~}>$10.~0'2+"0,-:>$

Eine kleine Erklärung? (Hinweis: BM bedeutet Back-Memory ):

// === Input and informations storing ===

2'  // Go to the 3rd cell (the two first will be used to store informations)
(   // Ask the user for a string (it will be stored as a suite of ASCII codes)
`   // Go the end of the string
>   // Make a new cell
0.  // Put a 0 to mark the end of the string
>   // Make a new cell, here will be stored the first random number
{@} // Store its adress in BM
0'  // Go to the 1st cell
{v} // Paste the adress, now the 1st cell contains the adress of the first random number
2-  // Subtract 2 because the string starts at adress 2 (the 3rd cell)
2'  // Go to the 3rd cell (where the string begins)

// === String encryption and displaying ===

0,  // While the current cell doesn't contain 0 (while we didn't reach the string's end)
  {@}  // Store the character's adress into the memory
  1'   // Go to the 2nd cell
  {v}  // Paste the value, now the 1st cell contains the adress of the current char
  0'   // Go to the 1st cell
  {+}  // Add the adress of the first random number to the current char adress
  {'}  // Go to this adrses
  9%+  // A random number between 0 and 10
  {^}  // Store this number in BM
  {1-} // Decrease BM (random number between 0 and 9)
  1'   // Go to the 1st cell
  "    // Go to the adress pointed by the cell (the adress of the current char)
  {+}  // Add it to the random number value
  {~}  // Display it as an ASCII character
  >    // Go to the next cell (the next character)
$   // End of the loop
10. // Set the new line's ASCII code into the current cell (which is now useless, so it can be overwritten)
~   // Display the new line
0'  // Go to the first cell
2+  // Add 2 to the adress, because we are not in the string loop : we cancel the 2 substraction
"   // Go to the pointed adress (the first random number's one)

// === Display the random numbers ===

0,  // While we didn't reach the end of the random numbers suite
    // That was why I stored numbers between 1 and 10, the first equal to 0 will be the end of the suite
  - // Decrease it (number between 0 and 9)
  : // Display the current random number as an integer
  > // Go to the next cell (the next number)
$ // End of the loop

Das scheint jetzt größer zu sein, stimmt: p? Vielleicht ist es möglich, diesen Code zu optimieren, aber im Moment ist das der kürzeste, den ich gefunden habe.


0

C #, 174 Bytes

using static System.Console;class b{static void Main(){var c=new System.Random();var d="\n";foreach(var e in ReadLine()){var f=c.Next(10);Write((char)(e+f));d+=f;}Write(d);}}

Ungolfed:

using static System.Console;

class b
{
    static void Main()
    {
        var c = new System.Random();
        var d = "\n";

        foreach (var e in ReadLine())
        {
            var f = c.Next(10);
            Write((char)(e + f));
            d += f;
        }

        Write(d);
    }
}

Wirklich ziemlich unkompliziert.


0

Perl 6: 55 oder 70 Bytes

Als anonyme Funktion, die einen Zeichenfolgenparameter verwendet und eine Liste mit zwei Zeichenfolgen (54 Zeichen, 55 Byte) zurückgibt :

{my @n=^9 .roll(.ords);(.ords Z+@n)».chr.join,@n.join}

Als Programm, das aus STDIN liest und in STDOUT schreibt (69 Zeichen, 70 Bytes) :

my @a=get.ords;my @n=^9 .roll(@a);say (@a Z+@n)».chr.join;say @n.join
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.