Компьютерный шифр

14

Вступление:

У меня есть множество разных шифров, которые хранятся в документе, который я однажды скомпилировал в детстве, я выбрал несколько из тех, которые, по моему мнению, лучше всего подходили для испытаний (не слишком тривиально и не слишком сложно), и превратил их в задачи. Большинство из них все еще находятся в песочнице, и я пока не уверен, выложу ли я все из них или только несколько. Но вот первый из них, чтобы начать вещи.


Компьютерный Шифр ​​зашифрует данный текст в «случайные» группы символов данного length. Если такая группа содержит цифру, она будет использовать эту цифру для индексации в своей собственной группе для зашифрованного символа. Если в группе нет цифр, это означает, что используется первый символ.

Например, допустим, мы хотим зашифровать текст this is a computer cipherс заданной длиной 5. Это потенциальный результат (примечание: числа приведены в 1 в следующем примере):

t     h     i     s     i     s     a     c     o     m     p     u     t     e     r     c     i     p     h     e     r       (without spaces of course, but added as clarification)
qu5dt hprit k3iqb osyw2 jii2o m5uzs akiwb hwpc4 eoo3j muxer z4lpc 4lsuw 2tsmp eirkr r3rsi b5nvc vid2o dmh5p hrptj oeh2l 4ngrv   (without spaces of course, but added as clarification)

Давайте возьмем несколько групп в качестве примеров, чтобы объяснить, как расшифровать группу:

  • qu5dtЭта группа содержит цифру 5, так что (1-индексированный) пятый символ этой группы является символ , используемый для расшифрованного текста: t.
  • hpritЭта группа не содержит цифр, поэтому первый символ этой группы неявно используются для расшифрованного текста: h.
  • osyw2: Эта группа содержит цифру 2, так что (1-индексированный) второй символ этой группы является символ , используемый для расшифрованного текста: s.

Вызов:

Учитывая целое число lengthи строку word_to_encipher, выведите случайную зашифрованную строку, как описано выше.

Вам нужно только зашифровать с учетом lengthи word_to_encipher, так что нет необходимости создавать программу / функцию дешифрования. Я мог бы сделать часть 2 вызов для расшифровки в будущем, однако.

Правила вызова:

  • Вы можете предположить, что lengthбудет в диапазоне [3,9].
  • Вы можете предположить, что word_to_encipherзавещание будет содержать только буквы.
  • Вы можете использовать либо строчные, либо прописные буквы (укажите, какой из них вы использовали в своем ответе).
  • Ваши выводы, каждая группа и позиции цифр в группе (если они есть) должны быть равномерно случайными . Таким образом, все случайные буквы алфавита имеют одинаковую вероятность возникновения; позиция зашифрованной буквы в каждой группе имеет одинаковую вероятность появления; и позиция цифры имеет такую ​​же вероятность появления (за исключением случаев, когда это первый символ и цифры не присутствуют; и она, очевидно, не может находиться в той же позиции, что и зашифрованный символ).
  • Вам также разрешено использовать 0-индексированные цифры вместо 1-индексированных. Пожалуйста, укажите, какой из двух вы использовали в своем ответе.
  • Цифра 1(или 00-индексированная) никогда не будет присутствовать в выходных данных. Так b1ndhчто не является допустимой группой для шифрования символа «b». Тем не менее, b4tbwявляется действительным, где 4зашифровывает bна 4 - м (1-индексированного) положении, а также другие символы b, t, wявляются случайными (который по совпадению также содержит b). Другие возможные действительные группы length5 , чтобы зашифровать символ «B» являются: abcd2, ab2de, babbk, hue5bи т.д.

Основные правила:

  • Это , поэтому выигрывает самый короткий ответ в байтах.
    Не позволяйте языкам кода-гольфа отговаривать вас от публикации ответов на языках, не относящихся к кодексу. Попробуйте найти как можно более короткий ответ для «любого» языка программирования.
  • Стандартные правила применяются к вашему ответу с правилами ввода / вывода по умолчанию , поэтому вы можете использовать STDIN / STDOUT, функции / метод с правильными параметрами и типом возврата, полные программы. Ваш звонок.
  • По умолчанию лазейки запрещены.
  • Если возможно, добавьте ссылку с тестом для вашего кода (например, TIO ).
  • Кроме того, добавление объяснения для вашего ответа настоятельно рекомендуется.

Тестовые случаи:

Input:
 Length:           5
 Word to encipher: thisisacomputercipher
Possible output:
 qu5dthpritk3iqbosyw2jii2om5uzsakiwbhwpc4eoo3jmuxerz4lpc4lsuw2tsmpeirkrr3rsib5nvcvid2odmh5phrptjoeh2l4ngrv

Input:
 Length:           8
 Word to encipher: test
Possible output:
 ewetng4o6smptebyo6ontsrbtxten3qk

Input:
 Length:           3
 Word to encipher: three
Possible output:
 tomv3h2rvege3le
Кевин Круйссен
источник
2
Как означает «униформа»
l4m2
@ l4m2 Равный шанс для любого выхода. Таким образом, все случайные буквы алфавита имеют одинаковую вероятность возникновения; позиция зашифрованной буквы в каждой группе имеет одинаковую вероятность появления; и позиция цифры имеет такую ​​же вероятность появления (за исключением случаев, когда это первый символ и цифра отсутствует, а также не в той же позиции, что и зашифрованный символ).
Кевин Круйссен
Так abcd2, ab2de, babbkвсе же? И b1akkдействует?
14 кв.
@ l4m2 Да, все три возможных выхода, зашифровывающих символ «b». Что касается b1akkя бы сказал, нет. Отредактируйте его в описании задачи, чтобы уточнить. Если первый символ является зашифрованным, цифра не должна присутствовать.
Кевин Круйссен
1
Например, когда длина = 3, символ = "а"; Форма "a??"имеет 676 возможных результатов, но "1a?", "?a1", "2?a", "?2a", имеет only104 результаты. Итак, если я пытаюсь выбрать один результат из всех этих 780 результатов, распределение «положения зашифрованной буквы» будет 13: 1: 1, а не 1: 1: 1. И я бы отнесся к этому как к "равномерно случайной" работе.
TSH

Ответы:

3

Pyth, 22 байта

smsXWJOQXmOGQJdO-UQJJz

Попробуйте онлайн.

Используются строчные и нулевые индексы.

объяснение

Очень простой алгоритм.

                           Implicit: read word in z
                           Implicit: read number in Q
 m                   z     For each char d in z:
      OQ                     Choose a number 0..Q-1
     J                       and call it J.
         m  Q                Make an array of Q
          OG                 random letters.
        X     d              Place d in this string
             J               at position J.
    W                        If J is not 0,
   X                J        place J in this string
               O             at a random position from
                 UQ          0..Q-1
                -  J         except for J.
  s                          Concatenate the letters.
s                          Concatenate the results.
PurkkaKoodari
источник
5

Perl 6 , 125 байт

->\n{*.&{S:g{.}=(65..90)>>.chr.roll(n).join.subst(/./,$/,:th($!=roll 1..n:)).subst(/./,$!,:th($!-1??(^n+1$!).roll!!n+1))}}

Попробуйте онлайн!

Принимает ввод и вывод в верхнем регистре. Принимает ввод карри, вроде f(n)(string). Использует 1 индексацию.

Объяснение:

->\n{*.&{ ...  }}   # Anonymous code block that takes a number n and returns a function
     S:g{.}=        # That turns each character of the given string into
                          .roll(n)      # Randomly pick n times with replacement
            (65..90)>>.chr              # From the uppercase alphabet
                                  .join # And join
            .subst(                         ) # Then replace
                   /./,  ,:th($!=roll 1..n:)  # A random index (saving the number in $!)
                       $/               # With the original character
            .subst(                )    # Replace again
                   /./,$!,:th( ... )    # The xth character with $!, where x is:
                           $!-1??          # If $! is not 1
                                 (^n+1$!).roll       # A random index that isn't $!
                                               !!n+1  # Else an index out of range
Джо Кинг
источник
4

Python 2 , 187 177 176 156 154 148 байт

lambda l,s:''.join([chr(choice(R(65,91))),c,`n`][(j==n)-(j==i)*(n>0)]for c in s for n,i in[sample(R(l),2)]for j in R(l))
from random import*
R=range

Попробуйте онлайн!

Используются заглавные буквы и цифры с 0 индексами.

-3 байта, спасибо Кевину Круйссену

TFeld
источник
@KevinCruijssen Спасибо :)
TFeld
Что sample(R(l),2)[::1|-(random()<.5)]значит?
14 кв.
@ l4m2 Он берет 2 числа range(l)и тасует их. Но, видимо, образец не гарантирует порядок, поэтому он не нужен :)
TFeld
Вы не можете удалить круглые скобки (j==i)*(n>0)? Умножение имеет приоритет оператора над вычитанием, не так ли?
Кевин Круйссен
1
@KevinCruijssen Да, я забыл удалить их, когда у меня были некоторые проблемы
TFeld
3

R , 134 132 123 байт

function(S,n,s=sample)for(k in utf8ToInt(S)){o=k+!1:n
P=s(n,1)
o[-P]=s(c(P[i<-P>1],s(17:42,n-1-i,T)))+48
cat(intToUtf8(o))}

Попробуйте онлайн!

Принимает заглавные буквы.

Объяснение старого кода (в основном тот же подход):

function(S,n){s=sample				# alias
K=el(strsplit(S,""))				# split to characters
o=1:n						# output array
for(k in K){					# for each character in the string
P=s(n,1)					# pick a Position for that character
o[-P]=						# assign to everywhere besides P:
      s(					# a permutation of:
	c(P[i<-P>1],				# P if it's greater than 1
		s(letters,n-1-i,T)))		# and a random sample, with replacement, of lowercase letters
o[P]=k						# set k to position P
cat(o,sep="")}}					# and print
Giuseppe
источник
2

Java (JDK) , 193 байта

s->n->s.flatMap(c->{int a[]=new int[n],i=n,x=0;for(;i-->0;)a[i]+=Math.random()*26+97;a[i+=Math.random()*n+1]=c;x+=Math.random()*~-n;if(i>0)a[x<i?x:x+1]=48+i;return java.util.Arrays.stream(a);})

Попробуйте онлайн!

  • Индекс основан на 0.
  • Эта запись использует IntStream(получено String::chars) в качестве ввода, а также число и возвращает другое IntStream.
  • Из- за взлома приведение doubleк intне нужно +=.
Оливье Грегуар
источник
2

Japt , 29 байт

;£=VöJ;CöV hUÎX hUÅÎUÎ?UÎs:Cö

Попробуйте онлайн!

Zero-индексироваться.

Объяснение:

;                                :Set C = [a...z]
 £                               :For each character of the input:
  =VöJ;                          : Get two different random indexes from [0,length)
       CöV                       : Get 5 random letters
           hUÎX                  : Replace one at random with the character from the input
                hUÅÎ             : Replace a different random character with:
                    UÎ?          :  If the input character was not placed at 0:
                       UÎs       :   The index of the input character
                          :      :  Otherwise:
                           Cö    :   A random letter
                                 :Implicitly join back to a string
Камил Дракари
источник
2

C, 115 байтов

g(_,n)char*_;{int i=rand(),j=i%~-n,k=0;for(i%=n;k<n;k++)putchar(k-i?!i|i<k^k-j?rand()%26+97:48+i:*_);*++_&&g(_,n);}

Попробуйте онлайн!

0-индексированный, строчные.

Слегка раскатанный и расширенный:

g(char*_,int n) {
    int i = rand(), j = i%(n-1), k = 0;
    for(i = i%n; k<n; k++)
        putchar(k!=i ? i!=0 || k==j + (k>i)
                          ? rand()%26 + 'A'
                          : i + '0')
                    : *_);
    if (*++_!=0) g(_,n);
}

Код должен быть довольно простым. Два случайных числа i, jсгенерированные в одном rand()вызове, являются независимыми, поскольку gcd ( n, ~-n) = 1 иRAND_MAX является большим.

attinat
источник
1
Добро пожаловать в PPCG! :)
Лохматый
1

чистый , 256 байт

import StdEnv
s::!Int->Int
s _=code {
ccall time "I:I"
ccall srand "I:I"
}
r::!Int->Int
r _=code {
ccall rand "I:I"
}
$n|s 0<1#k=map\e.r e rem n
=flatten o map\c.hd[map(\i|i==x=c=toChar if(i==y&&x>0)(x+48)(r i rem 26+97))[0..n-1]\\x<-k[0..]&y<-k[0..]|x<>y]

Попробуйте онлайн!

: выбирает

  • случайный x (позиция персонажа в сегменте)
  • случайный y , которое не равно x(положение цифры в сегменте)
  • случайная строчная буква для каждой позиции, не равной xи не равной, yесли не равен xнулю
Οurous
источник
1

JavaScript, 134 байта

l=>w=>w.replace(/./g,c=>eval("for(s=c;!s[l-1]||s[t?t-1||9:0]!=c;t=s.replace(/\\D/g,''))s=(p=Math.random()*36**l,p-p%1).toString(36)"))

Попробуйте онлайн!

Этот ответ выбрал закодированную строку из всех возможных закодированных строк равномерно. Таким образом, можно сделать закодированное письмо первым.

ТТГ
источник
1

C # (интерактивный компилятор Visual C #) , 171 байт

s=>n=>{var r=new Random();return s.SelectMany(c=>{int i=r.Next(n),j=r.Next(n-1);j+=j<i?0:1;return new int[n].Select((_,k)=>(char)(i==k?c:j==k&i>0?i+49:r.Next(26)+97));});}

Попробуйте онлайн!

Объяснение ...

// s is the input string
// n is the input length
s=>n=>{
  // we need to create an instance
  // of Random and use throughout
  var r=new Random();
  // iterate over s, each iteration
  // returns an array... flatten it
  return s.SelectMany(c=>{
    // i is the position of the letter
    // j is the position of the number
    int i=r.Next(n), j=r.Next(n-1);
    // ensure i and j are different
    j+=j<i?0:1;
    // create an iterable of size n
    return new int[n]
      // iterate over it with index k
      .Select((_,k)=>(char)(
        // return the letter
        i==k?c:
        // return the number
        j==k&i>0?i+49:
        // return a random letter
        r.Next(26)+97)
      );
  });
}
Dana
источник
1

Древесный уголь , 35 30 байт

NθFS«≔‽θη≔∧η‽Φθ⁻κηζFθ≡κζIηηι‽β

Попробуйте онлайн! Ссылка на подробную версию кода. 0 индексированные. Объяснение:

Nθ

Введите длину.

FS«

Введите слово и зациклите символы.

≔‽θη

Выберите случайную позицию для расшифрованной буквы.

≔∧η‽Φθ⁻κηζ

Выберите другую случайную позицию для цифры, если только буква не находится в позиции 0, в этом случае цифра также должна быть в позиции 0.

Fθ≡κ

Зациклите один раз для каждого выходного символа и включите положение.

ζIη

Если это позиция цифры, выведите позицию расшифрованной буквы.

ηι

Но если это позиция расшифрованной буквы, выведите букву. Это имеет приоритет над положением цифры, потому что Древесный уголь берет последнюю запись, если несколько вариантов переключения имеют одинаковое значение.

‽β

В противном случае выведите случайную букву.

Нил
источник
0

05AB1E , 26 байт

ε²Ý¨Ω©A.r²£Šǝ®Āi®²Ý¨®KΩǝ]J

0 индексированные.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

ε            # Map over the characters of the first (implicit) input-string:
 ²Ý¨         #  Create a list in the range [0, second input)
    Ω        #  Get a random item from this list
     ©       #  Store it in the register (without popping)
 A           #  Push the lowercase alphabet
  .r         #  Shuffle it
    ²£       #  Leave only the first second input amount of characters
      Š      #  Triple swap, so the stack order becomes:
             #  random index; random string; map-character
       ǝ     #  Insert the map-character at this random index into the random string
 ®Āi         #  If the random index was NOT 0:
    ®        #   Push the random index
    ²Ý¨      #   Push the list in the range [0, second input) again
       ®K    #   Remove the random index from this list
         Ω   #   Get a random item from this list
          ǝ  #   Insert the first random index at the second random index into the string
]            # Close both the if-else and map
 J           # Join all strings together (and output implicitly)
Кевин Круйссен
источник