Створіть шифр


15

Створіть шифр із заданим числом та рядком

Ваше завдання просте. Враховуючи рядок sі число 0 <= n <= 9в якості входів, вставляйте псевдовипадковий символ ASCII для друку між кожним символом рядків n. Такі, що для кожного персонажа між ними sє nвипадкові символи. Проміжки повинні бути оброблені.

Вхід:

  • строкова sфраза для шифрування в шифрі
  • ціле число nв діапазоні0 <= n <= 9

Приклад:

Вхід:

The treasure is here
2

Вихід:

T ! 0 h 32 e F4 t 0i r lk e hm a 7y s # 0 u * & r * h e ! 2 i H ^ s B, h ! @ E 0) r $ h e


Це тому найкоротший код виграє! Хай щастить!


3
випадковий символ для друку ASCII Ви повинні визначити, що тут означає випадкові . Чи всі друковані символи ASCII мають однакову ймовірність? Чи повинні вони бути статистично незалежними? Яку гнучкість ми маємо щодо цього?
Луїс Мендо

3
@jacksonecac Я не згоден. Просто сказати випадковим не достатньо. Наприклад, якщо я вибираю лише випадкових символів з рівними кодами ASCII, це все-таки випадково, але це, мабуть, не прийнято (чи це правда?) Якщо кожна серія nсимволів складається з nкопій одного і того ж випадкового символу, вони все одно є випадковими, але вони не є статистично незалежними. І так далі
Луїс Мендо

5
@jacksonecac "випадковий" - це дуже широкий термін. Чи можу я вибрати символів із нормальним розподілом, щоб символи навколо Oбули швидше, ніж пробіли чи ~? Якщо вона має бути рівномірною, то слід сказати це прямо. І якщо це не повинно бути рівномірним, то вам слід принаймні констатувати щось на зразок кожного символу, який повинен мати ненульову ймовірність. Ви також вказані в попередньому коментарі , що кожен символ має мати незалежний розподіл, так що, якщо це важливо, слід зазначити , в завданню. Існує дуже широкий спектр випадковості.
Мартін Ендер

3
Це насправді не шифр. Можливо, це стеганографічне.
Грег Мартін

2
Це не відповідна відповідь на дійсну точку @MartinEnder. Рішенням було б чітко вказати, що персонажі повинні бути однаковими та статистично незалежними один від одного, і коментарі припиняться. Альтернативною (але більш відкритою для зловживань) специфікацією є те, що перекошені дистрибутиви або ті, де символи залежать один від одного, добре, доки всі символи мають ненульову можливість виникнення. У коді специфікація гольфу важлива для справедливості. Оскільки ви не хочете звертатися з цими дійсними коментарями щодо інакше гарного виклику, я голосую за завершення.
Річка Рівня Св.

Відповіді:


7

C #, 141 131 байт

Досить схожий на відповідь Java @ @ Geobit , за винятком більш тривалого :(

(I,n)=>{var R=new System.Random();var o="";int i,r;foreach(var c in I)if(c>32)for(i=r=0,o+=c;i++<n;){r=R.Next(33,127);o+=(char)r;}return o;};

Повна лямбда:

Func<string, int, string> a = (I,n) =>
{
    var R=new System.Random();
    var o="";
    int i;
    foreach(var c in I)
        if(c>32)
            for(i=0,o+=c;i++<n;o+=(char)R.Next(33,127));
    return o;
};

чому R=...Ви можете просто безпосередньо використовувати, new System.Random().Next(...)я думаю,
Роман Gräf

2
@ RomanGräf msdn.microsoft.com/en-us/library/h343ddh9(v=vs.110).aspx Досвідчений клас C #, без насіння, використовуватиме системний годинник, тож якщо ви зателефонуєте у швидкій послідовності цикл там), більшість значень в кінцевому підсумку ідентичні, що не спрацювало б у більшості випадків: (Повірте, я завжди намагаюся, а потім пам’ятаю про це.
Yodle

7

05AB1E , 11 байт

ð-vy²FžQ.RJ

Спробуйте в Інтернеті!

Пояснення

ð-           # remove spaces from input string
  v          # for each char in the string
   y         # push the char
    ²F       # input-2 number of times do:
      žQ.R   # push a random ascii character
          J  # join to string

закрити! обріжте пробіли! :)
jacksonecac

@jacksonecac: Пропустив цю частину вибачте. Виправлено зараз :)
Emigna

хороша робота! що працює!
jacksonecac

1
@carusocomputing: Це додає також випадкові символи після останньої літери. Не тільки між літерами.
Емінья

1
@Emigna Після нещодавнього коментаря під питанням це здається нормальним :)
geisterfurz007

6

Java 7, 132 124 байт

String f(int n,char[]a){String o="";int i;for(char b:a)if(b>32)for(i=0,o+=b;i++<n;o+=(char)(33+Math.random()*94));return o;}

Нічого фантазійного, лише подвійний цикл, як ви очікували. Зовнішня для циклу рядка, внутрішня для заповнення randoms:

String f(int n,char[]a){
    String o="";
    int i;
    for(char b:a)
        if(b>32)
            for(i=0,
                o+=b;
                    i++<n;
                        o+=(char)(33+Math.random()*94));
    return o;
}

Не потрібно k: String f(int n,char[]a){String o="";for(char b:a)if(b>32){o+=b;for(int i=0;i++<n;o+=(char)(33+Math.random()*94));}return o;}(125 байт)
Олів'є Грегоар

Ой так. Я використовував це іншим методом. Не думав про те, щоб зняти це, коли я пішов з charакторським складом. Спасибі!
Геобіц

Моє ліжко. Я неправильно рахував, моя пропозиція також складала 124 байти: я перевіряв стовпчик замість довжини;)
Олів'є Грегоар

Так, я помітив, що порівнюючи двох :)
Геобіт

5

Пайк, 12 11 9 байт

d-FQV~KHs

Спробуйте тут!

d-        -  remove spaces from input
  F       - for i in ^:
   QV     -  repeat (number) times:
     ~KH  -    random_from(printable)
        s -   sum(^)

Відстеження випадкових символів нормально згідно з ОП.


5

Октава, 43 байти

@(s,n)[s(s>32);33+94*rand(n,nnz(s>32))](:)'

Це вводить рядок sі ціле число nяк вхід. Рядок в Octave - це просто масив символів. s>32- це логічна карта 1для будь-яких непросторових характерів. Код додає матрицю із nрядками та такою ж кількістю стовпців s(s>32), що й число, що містить числа з плаваючою комою між 33 та 126. Він неявно округляється до цілих чисел та перетворюється на ASCII-символи, коли він з'єднаний з рядкомs . (:)'випрямляє це до горизонтального масиву символів.

Тестуйте його тут!


1
Неявне округлення! Ніцца
Луїс Мендо

4

Пітон 2, 123 122 118 114 98 Байт

Людина, я хотів би randomне так дорого (і щоб нам не довелося фільтрувати місця). Тепер ми маємо великі заощадження від того, щоб дозволити мати символи шифру в кінці :) У будь-якому випадку, ось вам:

from random import*
f=lambda s,n:s and(' '<s[0])*eval('s[0]'+'+chr(randint(32,126))'*n)+f(s[1:],n)

4

JavaScript (Firefox 30+), 96 байт

(s,n)=>s.replace(/. */g,x=>x[0]+String.fromCharCode(...[for(_ of Array(n))Math.random()*95+32]))

Чистий ES6 на два байти довше:

(s,n)=>s.replace(/. */g,x=>x[0]+String.fromCharCode(...[...Array(n)].map(_=>Math.random()*95+32)))

Ось дуже класний підхід, який на жаль на 26 байт довше:

(s,n)=>String.raw({raw:s.split` `.join``},...[for(_ of s)String.fromCharCode(...[for(_ of Array(n))Math.random()*95+32])])

Власне кажучи, /. *(?=.)/це не працює для рядків, що починаються чи закінчуються пробілами, не те, що когось цікавить. (Зараз вам навіть дозволено відстежувати випадкових персонажів.)
Ніл

@Neil Дозволені випадкові символи? Я думаю, що я можу просто видалити те, (?=.)що займає пробіли в кінці рядків.
ETHproductions

Характеристика не настільки чітка, але я думаю, що ви не повинні вставляти порожні пробіли, тому 94+33замість95+32
edc65


3

CJam , 21 18 байт

lS-(ol~f{{95mrSc+\}*}

Спробуйте в Інтернеті!

Друкує n випадкових символів, що відкладаються.

Пояснення

lS-        e# Read line and remove spaces.
l~         e# Read and evaluate another line.
f{         e# For each character (passing in N)...
  {        e#   Do this N times...
    95mr   e#     Push random integer in [0, 95).
    Sc+    e#     Add to space character, giving a random printable ASCII character.
  }*
}
           e# All characters remaining on the stack are printed implicitly
           e# at the end of the program.

3

Bash, 124 байти

Чистий bash + coreutils , відсутні структури управління потоком, ніякі підмовні мови, не "eval"

Гольф

E() { N=${1// /};paste <(fold -1<<<$N) <(tr -cd "\\40-\\176"<\/dev\/urandom|head -c$(($2*${#N}-$2))|fold -$2)|tr -d '\t\n';}

Тест

>E "The treasure is here" 2
TkZhf(e&Rt@FrS,edha+-sJTuh.rX@eVKi+3s<7hftey8r*/e

3

Q / KDB +, 39 36 34 байт

raze{""sv(raze x;`char$40+n?87)}prior s
(,/)({""sv((,/)x;`char$40+n?87)}':)s

(,/)({""sv((,/)x;10h$40+n?87)}':)s

Використовувані змінні:

s:"The treasure is here"
n:2

Для цього використовується попереднє прислівник, яке застосовує функцію, яка знаходиться ліворуч між кожним елементом праворуч та його попередником. (По суті, застосовує функцію зліва між кожним символом праворуч.)

Створіть n випадкових чисел між 40 і 126, а потім перетворіть їх у еквівалент символів: (у здається, що для них є лише символи)

`char$40+n?87

//Possible characters.
()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~

Приклад виводу:

TVghrveVp Rpti+r0sea3a9nsIjuRXrAReJ; +di=ys`{ ikhKTe4trTZesz

EDIT:
Збережено 3 байти, перетворивши q'''''''''''''''''' '' (в / /), використовуючи позначення k, і аналогічно змінено до `: Дякую @slackwear за оновлення, поголив 2 байти :)


1
Ви можете зберегти пару байтів, кинувши за допомогою10h$
skeevey

2

Java 8, 114 байт

Гольф

(n,s)->s.chars().forEach((c)->{if(c>32)for(int i=0;i<=n;)System.out.print((char)(++i==1?c:33+Math.random()*94));})

Лямбда, яка приймає цілий чи рядок. Натхненний відповіддю Java 7, подвійний цикл, використовуючи деякі синтаксиси потоку Java 8 (String.chars ), щоб зберегти кілька байт.

Вхідні дані

3, "Hello world!"

Вихідні дані

HfKIedb3l<-Ul%}vod"Bw\"|oa`%rH-}l/-{dMS;!B#X

2

Скала, 95 94 байт

def c(s:String,i:Int)=s.filter(_>32).mkString(scala.util.Random.alphanumeric.take(i).mkString)

Нічого надто фантазійного, окрім використання mkString на String. Він розглядає рядок як список символів і дозволяє мені вставити роздільник між ними. Мій роздільник - відповідна кількість випадково генерованих буквено-цифрових символів.


Не зовсім відповідає на питання. Характер Random.alphanumericспричинить кожен шматок однаковий, тому це кульгавий шифр. Дивіться цей приклад:scala> c("Hello", 1) res0: String = Hbeblblbo
Яків

До речі, ви можете видалити filter. Викликання mkStringна рядку вважатиме це колекцією персонажів.
Яків

@Jacob фільтр - це найефективніший спосіб, про який я міг би придумати видалення пробілів. Я залишив випадковий так, як це здалося достатнім, але якщо я встигну, я додаю окрему функцію для належного випадкового тексту.
Етан

2

> <> (Риба), 107 106 103 байт

<v}:{r&" "
1xv+
2<v+
v}<
<~v!?=&:&:
6.>ol2-?!;a
:{{:}l1-[rv
v2<
<1x|!}:}-1<v!?:{{:o-+
^3<v ~}}r]~<
.40<

Спробуйте в Інтернеті!

Це не надвипадково, але випадково. Просто помістіть рядок і ціле число в стек (Приклад: "Привіт, світ!", 5).

Input: "Hello world!", 5
Output: H^\^]^eceeedldcdeclgfffhowhhfggojkkkkrdccedl]]\]\d

Повне пояснення

Це трохи старша версія коду, поки я не оновлюю пояснення. Це здебільшого те саме, просто, можливо, трохи простіше читати:

< v}:{r&" "
+1xv
+2<v
   }
:&:<~ v!?=&
?!;a6.>ol2-
:{{:}l1-[rv
v2<
<1x|!}:}-1<v!?:{{:o+*
^3<v ~}}r]~<
.43<

Ми зробимо вигляд, що параметр string є, sа параметр integer є i.

< v}:{r&" "

<Каже рибу негайно рухатися вліво, який обертає навколо " ", який додає простір characted в стек. Потім риба подорожує &, що додає місця до реєстру. rповертає стек і {:}зміщує стек вліво (ставлячи iна кінець стека), копіює значення на кінець стека, а потім зміщує його вправо. vкаже рибі почати рухатися вниз.

+1xv
+2<v
   }

xвказує рибі рухатися у випадковому напрямку, в кінцевому підсумку в результаті риба рухається праворуч і продовжується вниз, або проходить над 1+або 2+попередньо. Вони додають відповідно 1 або 2 до числа на кінці стеку. Якщо риба рухається вгору, вона б’є vзнову і рухається назад вниз. }зміщує стек вправо, після чого, перебуваючи iв позиції 1 на стеку, і ця нова змінна в позиції 0 (ми називаємо це m).

:&:<~ v!?=&

Цей розділ є функцією, назвемо його whitespaceTrimmer . Починається там, де <є. Він просто знімає пробіли, які знаходяться на кінці стека (так це початок рядка), поки він не перетвориться на непробільний символ.

Тож риба одразу запливає в a <і повинна подорожувати зліва. Потім він запускає, в :&:&який копіює значення на кінці стека, розміщує простір з регістра на кінець стека, копіює його, а потім повертає його назад до регістра.

Потім риба потрапляє =?!v ~, а точніше, =яка вискакує останні два значення (два, що ми тільки що створили) зі стека, порівнює їх, ставить 1 на кінці стеку, якщо вони рівні, і 0 на кінець стека, якщо вони різні. ?Вискакує нове значення з кінця стека, якщо 0 воно не виконує таку інструкцію, яка в даному випадку !, замість цього він виконує v, який замовляє рибу рухатися вниз (вихід з функції).

Якщо це 1, то він знайшов пробіл, тому він виконує !батут, і це змушує рибу пропустити наступну інструкцію, яка є v, тому риба продовжується. Перед рибою він бачить, ~яке вказує їй вивести останнє значення зі стека (підтверджено пробіл), потім риба продовжує і знову запускає функцію.

?!;a6.>ol2-

Рибі негайно кажуть плавати прямо, а >потім виводити останнього символу на стек o(який, вперше це запускається, є першим символом s). Він отримує довжину стека від l, розміщує a 2на кінці стека, а потім -призводить до віднімання 2 l. Це вражає, ?!;що, пам’ятаючи, що ?це робить, змушує рибу пропускати, !якщо стек порожній, і приземляється ;, що закінчує програму.

Слідом за тим, якщо на стеку є ще символи, ми виконуємо, !що змушує рибу підстрибувати над ;та виконувати a6., що зберігає a(AKA 10), і 6в кінці стека, які є x, yкоординатами для ., що вискакує на них у кінці стека, потім телепортує рибу до 10, 6та виконує інструкцію праворуч від цього пози (як риба плаває правильно).

Це менш складно, ніж це звучить, коли ви усвідомлюєте, що yпозиція 6 - це рядок нижче цього. xпозиція 10 - то v, і праворуч від того , що є неоператором. Це змушує рибу продовжувати плавати правильно і насправді починати виконання на початку рядка ...

:{{:}l1-[rv
v2<
<1x|!}:}-1<v!?:{{:o+*
^3<v ~}}r]~<
.43<

Отже, це функція, яка додає випадковий текст між символами. Це трохи рот, але це лише тому, що я намагався зробити це трохи зайвим випадковим чином. Назвемо цей genRandomChars .

Це :{{:}l1-[rvнасправді налаштування для функції, і менш того, частина фактичної самої функції. Спочатку риба плаває, над :{{якою копіює значення на кінці стеку, потім двічі зміщує її вліво. Якщо ви пам'ятаєте, що це iбуло в позиції 1 на стеку, то ви знаєте i, що зараз на кінці стека.

Потім риба плаває над тими, :}хто копіює i, і зміщує стопку вправо, розміщуючи iяк на початку, так і в кінці стека. l1-[має риба розмістити довжину на кінці стеку, відняти 1 від неї, потім [створити новий стек, перемістивши l-1(довжина стека мінус 1) значення на новий стек (так що просто залишивши iна старій стеці). Тоді риба просто потрапляє, rvщо повертає стек знову (я думаю, що створення нового стека відміняє його чомусь), і наказує рибі ще раз плисти вниз, справді запускаючи функцію <внизу.

Таким чином, на даний момент кінець стека має mі наше тимчасове i, яке ми будемо називати ti. Одразу риба перепливає 1-}, яка віднімає 1 від tiі переміщує її до початку стека. Потім він :}просто копіює mі переміщує його до початку стека (ставлячи tiв позицію 1 стека).

Це коли ми потрапили на цю дрібницю:

v2<
<1x|!
^3<

Це насправді мертве просто. !Змушує рибу пропустити |і виконати x. Пам'ятаючи, що xробить, ми пам’ятаємо, що це змушує рибу рухатися в будь-яких 4 напрямках. |просто дзеркало, і змушує рибу плавати назад x. Отже, риба розмістить 1, 2 або 3 на кінці штабеля і продовжить рух вліво, обернувшись навколо.

Потім риба виконує, *+oщо спричиняє спливання останніх двох значень у стеку, множення разом, а результат відштовхується назад, потім те саме, що додається, потім кінцеве значення вискакує з стека і виводиться за допомогою o. Наш стек тепер відносно нормально знову , що містить тільки [ m, ti, s].

:}}:викликає sкопіювання значення на кінці стека (в основному положення 0), потім стек двічі зміщується вправо (знову розміщується tiна передній панелі), потім tiкопіюється. ?!vНа даний момент це має бути досить легко зрозуміти. В основному, якщо tiце 0, тоді ми виходимо з функції v, в іншому випадку виконуємо !і пропускаємо v(робимо інший цикл).

Якщо ti0 і ми виводимо трохи випадкові символи, то виконуємо vі бачимо:

   v ~}}r]~<
.43<

Тут нічого надто фантазійного. Видаляємо tiзі стека через ~. Тоді ]новий, він вискакує всі наші цінності зі стека та розміщує їх на старій стеці! З - за це питання розвороту ми зі зворотним r, то зрушувати стек вправо двічі }}~, shufting стек справа, що дає нам [ m, i, s], то ~є , щоб видалити зайву дубльовані s[0]раніше в функції , як ми повинні були б, якщо ми робили цикл (але це не так, ми виходимо). vговорить рибі плавати вниз і в >34.(перевернутий, щоб показати порядок виконання), який говорить рибі просто плавати ліворуч 3, 4(тому що .це стрибок!). 3, 4насправді просто праворуч від початкуwhitespaceTrimmer, що ідеально, тому що ми подорожуємо ліворуч.

Дотримуючись усієї цієї логіки, ми можемо слідувати за рибою до тих пір, поки стек остаточно не порожній і програма не завершиться після whitespaceTrimmerвиконання.


Хм, я не бачив, що цей символ повинен бути надрукований. Для цього знадобиться незначна модифікація, яка може зробити її менш випадковою і меншою.
redstarcoder

Це насправді не виглядає набагато менш випадково. Я вважаю, що це повинно працювати в більшості випадків, у мене його ще не було. Він напевно буде працювати з великими або малими літерами та деякими символами. Я впевнений, що це відповідає вимогам завдання.
redstarcoder

2

Perl 5, 81 байт

($_,$n)=<>;chomp;y/ //d;$\=chop;print map{$_,map{chr 33+int rand 94}1..$n}split//

Я сподіваюся, що наступне допоможе вам зрозуміти, що робить однолінійний:

($_, $n) = <STDIN>;  # Reads in the string into $_,
                     # and the number into $n, from standard input.
                     # (<STDIN> works slightly different from <>.)
chomp($_);           # Removes the newline from the string.
$_ =~ tr/ //d;       # `Tr/`ansliterates ASCII space characters
                     # into nothing, effectively `/d`eleting them.
$\ = chop($_);       # Chop()s off the last character out of $_ and
                     # appends it to the output when print()ing.
                     # (Perl always prints $\ after you call print().)
print( map {         # Each element of [List 1] will be mapped to:
    $_,              #   -- Itself, and
                     # (When mapping, each element is available as $_.)
    map {            # (`map` resembles `foreach` but returns a list.)
        chr(         #   -- A random ASCII character, in the range
          33 + int(rand(94)) ) # from 33 (!, hex 21) to 126 (~, hex 7E)
    } 1..$n          # ...$n times! (Over the range 1 to $n, actually.)
} split(//, $_) );   # [List 1] is $_, split() into characters.

1

Clojure, 126 123 118 122 117 байт

(defn c[m n](apply str(remove #(=\space %)(mapcat #(apply str %(for [_(range n)](char(rand-nth(range 32 127)))))m))))

Мапа над повідомленням, вставляє випадкові символи, а потім об'єднує результат.

Інструкція передбачає, що всі пробіли повинні бути вилучені з результативного рядка. Якщо передбачається позбавлення лише пробілів у вихідному повідомленні, я можу це змінити.

Безголівки:

(defn cipher [message n]
  (apply str
    (remove #(= \space %)
        (mapcat #(apply str %
                     (for [_ (range n)]
                       (char (rand-nth (range 32 127)))))
                message))))

1

Пітон 3, 127 байт

import random
a,b=input(),input()
print(''.join([x+''.join([chr(random.randint(33,126))for c in range(int(b))]) for x in a]))

Напевно, шлях довший, ніж потрібно, але поки що це шахтний гольф.


1
Це додає випадкових символів перед першим символом, а пробіли не оброблені. Я думаю, що обидва ці речі порушують правила.
Стюі Гріффін


1

Пітон 3, 133 байт

from random import *
c=int(input())
print(''.join([i+''.join([chr(randint(33,126))for i in range(c)])for i in input().strip(' ')])[:-c])

1

Node.js, 88 байт

(s,n)=>s.replace(/./g,c=>c!=" "?c+crypto.randomBytes(n).toString`base64`.substr(0,n):"")

Приклади виходів:

f("The treasure is here", 2)
// THphdwekAtMArbSeU1aDTsZWuqnr2yek1iyUsKshqXewvrVCeTi

f("The treasure is here", 2)
// TYshlcep6t4Iru7e29aQ1sl/uvQrlzeSJihysDhhOLe1urpte1m

Спробуйте в Інтернеті!


1

C, 102 100 байт

-2 байти для пропуску continue.

i;f(char*s,int n){do{while(*s==32)++s;putchar(*s);i=n;while(i--)putchar(32+rand()%95);}while(*s++);}

Безголівки:

i;
f(char*s,int n){
 do{
  while(*s==32)++s;
  putchar(*s);
  i=n;
  while(i--)
    putchar(32+rand()%95);
 }while(*s++);
}

Використання:

main(){
  char a[]="A   A A";
  f(a,3);
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.