Zaimplementuj ten klucz szyfrujący

13

Zaimplementuj ten klucz szyfrujący

Cel

Użyj algorytmu (wyjaśnionego w sekcji Algorytm), aby zaimplementować określony szyfr.

Program musi odczytać dane wejściowe ze STDIN lub najbliższego dostępnego odpowiednika, użyć algorytmu do wygenerowania tekstu zaszyfrowanego i klucza.

Tekst zaszyfrowany i klucz zostaną zapisane w STDOUT lub najbliższym dostępnym odpowiedniku. Dowolny format jest dozwolony, o ile wyprowadza tekst zaszyfrowany i klucz.

Algorytm

Konwertuj znaki w ciągu na odpowiednie wartości ASCII. Na przykład:

Hello -> 72 101 108 108 111

Następnie musisz wygenerować klucz tak długi, jak ciąg z liczbami losowymi w zakresie 0–9.

Hello -> 62841

Dodaj liczby całkowite w losowej sekwencji liczb do wartości ASCII ciągu. W powyższych przykładach 72 zmieniłoby się na 78, a 101 na 104.

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

Następnie przekonwertuj nowe wartości z powrotem na znaki. W powyższych przykładach tekst Hellostał się Ngtpp.

Przykłady

(Są to tylko przykłady tego, jak może wyglądać wydruk. Wyjście może i będzie się różnić).

Hello World

Lfrlu)_supg
41606984343

This will be encoded

Zhjs$~koo gj$iuhofgj
60104723305544750226

Zasady

  • Możesz założyć, że dane wejściowe będą zawierać tylko znaki z zakresu az, AZ i spacji.
  • Zgłoszenia muszą być pełnymi programami lub funkcjami.
  • Zgłoszenia będą oceniane w bajtach.
  • Standardowe luki są zabronione.
  • To jest golf golfowy, więc wygrywa najkrótszy kod.

(To jedno z moich pierwszych wyzwań, jeśli coś jest nie tak, możesz mi powiedzieć, jak mogę to poprawić).

m654
źródło
5
To wyzwanie wygląda dla mnie dobrze, z wyjątkiem kilku przemyśleń. 1. Czy funkcja jest dozwolona zamiast pełnego programu? Powiązane pytanie brzmi: czy wartości mogą zostać zwrócone zamiast wydrukowane? 2. Powiedziałeś, że preferably with the format (ciphertext)\n(key).„preferowane funkcje” i golf golfowy nie mieszają się zbyt dobrze. Powinieneś uczynić to obowiązkowym lub zezwolić na inne formaty wyjściowe. 3. Czy klucz musi być wydrukowany bez spacji? A co z wydrukowaniem go np. W formie listy [0, 5, 2, ...]?
James
Czy klucz może mieć zera wiodące?
TheBikingViking
1
Dobre pierwsze wyzwanie, ale nie jestem pewien co do ścisłych formatów IO. Zwykle funkcje są dozwolone i zwykle odpowiedzi można odczytać z jednej z zaakceptowanych metod We / Wy. Obejmuje to generowanie tablicy z przedmiotami
Downgoat
1
Czy cyfry klucza muszą być generowane z jednolitym rozkładem?
Dennis
1
Uh ... 101 + 2 to 103, a nie 104. :-)
YetiCGN

Odpowiedzi:

5

Galaretka , 12 9 bajtów

⁵ṁX€’Ṅ+OỌ

Wypróbuj online!

Jak to działa

⁵ṁ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.
Dennis
źródło
5

Python 3, 130 bajtów

Dzięki @Rod za wskazanie błędu

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)

Funkcja, która pobiera dane wejściowe za pomocą argumentu jako ciąg i wypisuje do STDOUT.

Jak to działa

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

Wypróbuj na Ideone

TheBikingViking
źródło
Twój generator kluczy nie generuje kluczy zaczynających się od 0. zwiększenie granic 10-krotnie i usunięcie pierwszej cyfry powinno naprawić: m=10**len(x);k=str(randint(m,m*10))[1:];a nawet zapisujesz bajt w procesie c:
Rod
@Rod Dzięki za wskazanie błędu. Nie pozwoli to jednak zaoszczędzić żadnych bajtów, ponieważ randintjest włącznie, co oznacza, że ​​musisz to zrobić m*10-1. Właśnie wymyśliłem sposób, aby to naprawić dla tej samej liczby bajtów.
TheBikingViking
3

Pyth - 16 bajtów

Oczekiwanie na decyzję OP dotyczącą formatów wyjściowych.

sCM+VCMQKmOTQjkK

Pakiet testowy .

Maltysen
źródło
Zdecydowałem się na format.
m654,
3

Właściwie 17 bajtów

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

Wypróbuj online!

Wyjaśnienie:

;`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
Mego
źródło
2

CJam - 14 bajtów

Kiedy zobaczyłem matematykę ascii, wiedziałem, że muszę napisać odpowiedź CJam.

q_{;Amr}%_@.+p

Wypróbuj online tutaj .

Maltysen
źródło
2

MATL, 13 bajtów

"10r*]v!kGy+c

Dane wyjściowe wyglądają następująco:

9 5 8 2 1
Qjtnp

Wypróbuj online!

Wyjaśnienie:

"    ]          % 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
James
źródło
Nie jestem pewien, czy to jest właściwy format ...
Leaky Nun
@Leaky Nun Zmieniłem trochę zasady.
m654
@ m654 Gdzie powiedziałeś, że pomiędzy wartościami mogą być spacje?
Leaky Nun
@LeakyNun Pierwotnie obowiązywała ich zasada, ale ja ją usunąłem.
m654
1
Dobry pomysł na użycie pętli. Jest w rzeczywistości krótszy niż wersja z wieloma wejściami rlubYr
Luis Mendo,
2

PowerShell v2 +, 79 77 bajtów

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

Pobiera dane wejściowe $n, zapętla każdą postać i pobiera Randomelement z 0..9każdej iteracji. Przechowuje te liczby (jako tablicę) w $x. Ruruje tę tablicę do innej pętli. Każda iteracja pobiera bieżący element $_, dodaje go do pozycyjnego znaku wyciętego z $n(niejawne rzutowanie char-to-int), a następnie ponownie rzutuje jako [char]. Pozostawia to w przygotowaniu. Jest to zamknięte w parens i zmontowane -joinrazem, tworząc słowo. Zostało to w przygotowaniu. Ponadto numer $xjest również -joinedytowany razem i pozostawiony w potoku. Są one domyślnie drukowane z Write-Outputkońcem wykonania, co powoduje, że domyślnie są drukowane z nową linią.

Przykład

PS C:\Tools\Scripts\golfing> .\implement-this-key-cipher.ps1 'Hello World!'
Lhoot(Yt{mf"
433358259121
AdmBorkBork
źródło
2

C #, 252 247 245 232 216 bajtów

Rozmiar jest dość zły w porównaniu do innych rozwiązań, ale jednak ...

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

To jest moja druga odpowiedź na codegolf i jestem całkiem początkującym, biorąc pod uwagę C #, więc chętnie usłyszę, jak to skrócić :)

Nie golfowany:

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);
    }
}
  • Zaoszczędź 5 bajtów dzięki @FryAmTheEggman
  • Zapisano 2 bajty dzięki @theLambGoat
  • Zapisano 7 bajtów, usuwając staticz klasy p
  • Zaoszczędź 24 bajty dzięki @milk
Tom Doodler
źródło
1
Sztuka polega na tym, aby nie porównywać z innymi językami;) Nie jestem szczególnie dobrze zaznajomiony z C # golfem, ale czy możesz zrobić b++<i.Count()i pozostawić trzecią klauzulę pustą? Również nie sądzę, trzeba końcowego znaku nowej linii, więc ostatni dzwonek, aby WriteLinemógł być Writezamiast.
FryAmTheEggman,
Nie jestem również dobrze zorientowany w C #, ale myślę, że możesz przenieść = r.Next (10) do deklaracji d i zapisać zestaw nawiasów w trakcie zapisu. Czy przypadek nie zwraca int, więc nie możesz tego zrobić?
theLambGoat
Myślę, że mogę to zrobić, pozwól mi sprawdzić
Tom Doodler,
Możesz zamieniać typy na var. tzn. var c=zamiast string c=ogolić kilka bajtów.
mleko
Dlaczego nie zostawić wyniku Console.ReadLine()jako ciągu? i.Lengthjest krótszy niż i.Count(), nie potrzebujesz System.Linq. ciąg ma indeksatora znaków. Również tworzenie nowych obiektów losowe w pętli jest mniej bajtów: new Random().Next(10).
mleko
2

CJam, 11 bajtów

Nq{Amr_o+}/

Wypróbuj online!

Jak to działa

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.
Dennis
źródło
2

05AB1E , 18 17 bajtów

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

Wyjaśnienie

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

Wypróbuj online

Emigna
źródło
2

Python 3, 112 bajtów

c to funkcja, która zwraca zaszyfrowany tekst i klucz

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

Oto kod, który robi to samo i jest nieco bardziej czytelny

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

Wynik:

>>> text, key = c('Hello World')
>>> print(text, key, sep='\n')
Liuot#`oylk
44935390707
odrling
źródło
Witamy na tej stronie!
James
1

PHP, 63 86 82 bajtów

Edycja: zapomniałem wydrukować klucz ...

Dzięki Alex Howansky za uratowanie mnie 4 bajtów.

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

Dane wejściowe są przekazywane za pomocą argumentu wiersza poleceń. Bierze każdy znak w ciągu i dodaje losową liczbę całkowitą od 0 do 9 do kodu ASCII, a następnie konwertuje kod z powrotem na ASCII. Każda liczba losowa jest dołączana do $s, która jest drukowana na końcu.

Business Cat
źródło
Musisz również wydrukować klucz.
Alex Howansky
Możesz wstawić $s.=$rpo drugiej połowie w pętli for, oszczędzając bajt, ponieważ możesz zrzucić jego końcowe pół. Wtedy twoja pętla będzie tylko jedną instrukcją, więc możesz wyciąć nawiasy klamrowe, oszczędzając 2 dodatkowe bajty. Na koniec możesz umieścić $swewnątrz cytowanego ciągu, oszczędzając .operatorowi jeszcze jeden bajt. :)
Alex Howansky
@AlexHowansky: To bardzo prawda. Dzięki
Business Cat,
1

J, 32 bajty

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

odpowiednik python:

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)
ljeabmreosn
źródło
1

Perl, 34 bajty

Obejmuje +1 dla -p

#!/usr/bin/perl -p
s%.%$\.=$==rand 10;chr$=+ord$&%eg
Ton Hospel
źródło
0

Perl, 65 bajtów

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

Chwilę zajęło mi wymyślenie, jak uzyskać dane wejściowe bez nowej linii na końcu. Przyjmuje to jako argument linii poleceń

theLambGoat
źródło
Twoje rozwiązanie ma pewne problemy. Dane wejściowe nie są odczytywane ze STDIN, $;nie zaczynają się puste, więc drukuje starą treść, a rand nigdy nie może wygenerować 9. Są łatwe do naprawienia, a użycie STDIN
skróci
@TonHospel Zwykle wymagania dotyczące wprowadzania danych są luźne, a argumenty są akceptowane w stosunku do STDIN, a przy pobieraniu danych z STDIN jest krótszy, ale konieczność usunięcia z niego nowej linii wydłuża ją. I chociaż rand generuje liczby <9, metoda int Perla zaokrągla raczej niż podłogi, więc wszystko> = 8.5 powinno kończyć się jako 9
theLambGoat
Wymagania wejściowe są zwykle luźne, ale tutaj nie było. Pierwsze non przełamane od STDIN jest proste: <>=~/./g. I nie, intw perlu obcina się do 0, to nie zaokrągla. perl -wle 'print int 8.6'wyniki8
Ton Hospel
0

Python 2, 84 99 bajtów

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

Wykorzystuje id()wartość ciągu do generowania liczb losowych.

Spróbuj

atlasolog
źródło
Musisz wyprowadzić zarówno klucz, jak i tekst zaszyfrowany.
TheBikingViking
@ TheBikingViking nie wiem, jak to przeoczyłem. Dzięki - naprawiono
atlasolog
Myślę, że ma to ten sam problem, co wcześniejsza wersja mojej odpowiedzi w języku Python; nigdy nie produkuje kluczy z wiodącymi zerami.
TheBikingViking
@ TheBikingViking Naprawiono ponownie
atlasolog
zmienić map(chr,[ord(a)+int(b)for a,b in zip(x,y)])na map(lambda x,y:chr(ord(x)+int(y)),x,y)? to powinno coś uratować
ljeabmreosn
0

Senva , 74 bajty

Oto najkrótszy program, jaki stworzyłem:

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

Małe wyjaśnienie? (Uwaga: BM oznacza pamięć wsteczną ):

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

To wydaje się teraz większe, prawda: p? Być może można zoptymalizować ten kod, ale na razie jest to najkrótszy czas, jaki znalazłem.

ClementNerma
źródło
0

C #, 174 bajtów

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

Nie golfowany:

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

Naprawdę całkiem proste.

Scepheo
źródło
0

Perl 6: 55 lub 70 bajtów

Jako anonimowa funkcja, która pobiera parametr ciągu i zwraca listę dwóch ciągów (54 znaków, 55 bajtów) :

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

Jako program, który czyta ze STDIN i zapisuje do STDOUT (69 znaków, 70 bajtów) :

my @a=get.ords;my @n=^9 .roll(@a);say (@a Z+@n)».chr.join;say @n.join
smls
źródło