Crittografia pari / dispari ASCII


13

Definiremo il cifrario pari / dispari ASCII tramite lo pseudocodice seguente:

Define 'neighbor' as the characters adjacent to the current letter in the string

If the one of the neighbors is out of bounds of the string, treat it as \0 or null

Take an input string

For each letter in the string, do
  If the 0-based index of the current letter is even, then
    Use the binary-or of the ASCII codes of both its neighbors
  Else
    If the ASCII code of the current letter is odd, then
      Use the binary-or of itself plus the left neighbor
    Else
      Use the binary-or of itself plus the right neighbor
  In all cases,
    Convert the result back to ASCII and return it
  If this would result in a code point 127 or greater to be converted, then
    Instead return a space

Join the results of the For loop back into one string and output it

Ad esempio, per l'input Hello, l'output è emmol, poiché

  • I Hgiri a \0 | 'e'cui èe
  • Il eturno diventa 'e' | 'l', o 101 | 108, che è 109om
  • Il primo lsi trasforma anche in 101 | 108om
  • Il secondo lsi trasforma in 108 | 111, che è 111oo
  • Il oturno a 108 | \0, ol

Ingresso

  • Una frase composta esclusivamente da caratteri ASCII stampabili, in qualsiasi formato adatto .
  • La frase può contenere punti, spazi e altri segni di punteggiatura, ma sarà sempre e solo una riga.
  • La frase avrà una lunghezza di almeno tre caratteri.

Produzione

  • La cifra risultante, basata sulle regole sopra descritte, restituita come stringa o output.

Le regole

  • È accettabile un programma completo o una funzione.
  • Sono vietate le scappatoie standard .
  • Si tratta di quindi si applicano tutte le normali regole del golf e vince il codice più breve (in byte).

Esempi

Input su una riga, output su quanto segue. Le righe vuote separano esempi.

Hello
emmol

Hello, World!
emmol, ww~ved

PPCG
PSWG

Programming Puzzles and Code Golf
r wogsmmoonpuu ~ meannncoooeggonl

abcdefghijklmnopqrstuvwxyz
bcfefgnijknmno~qrsvuvw~yzz

!abcdefghijklmnopqrstuvwxyz
aaccgeggoikkomoo qsswuww yy

Test 123 with odd characters. R@*SKA0z8d862
euutu133www|todddchizsscguwssr`jS{SK{z~|v66

3
È davvero un codice? Non sembra essere un modo per decifrarlo.
pipe

Dato che le omodifiche a lnel primo esempio, sono abbastanza sicuro che le tue specifiche assicurino che il primo onon cambi lnel secondo esempio. Dovrebbe cambiare 'l' | ',', qualunque cosa sia, giusto?
Greg Martin,

@pipe Sì. Non proprio un "codice", ma non sono sicuro di come chiamarlo. Nemmeno in realtà è un hash. Dei tag che abbiamo, "cifratura" sembrava il più vicino, quindi è quello che ho scelto.
AdmBorkBork,

@GregMartin Sì, va a 'l' | ',', che è 108 | 44 --> 1101111 | 0101100, che diventa 108, che è l. Il ,accade per allinearsi con la l, quindi non c'è alcun cambiamento quando il binario o avviene.
AdmBorkBork,

Oh, è davvero il binario-O ... Stavo pensando al binario-XOR. Grazie per il chiarimento. D'altra parte, questo parla ancora di più all'osservazione di Pipe che questo "codice" non può essere realmente decifrato, per quanto ne so.
Greg Martin,

Risposte:



4

Perl, 63 62 byte

Include +4 per -lp

Dare input su STDIN

oddeven.pl:

#!/usr/bin/perl -lp
s%.%(--$|?$n|$':$&|(ord$&&1?$n:$'))&($n=$&,~v0)%eg;y;\x7f-\xff; ;

Funziona come mostrato, ma per ottenere il punteggio richiesto questo deve essere inserito in un file senza final ;e newline e le \xhhescape devono essere sostituite dai loro valori letterali. Puoi farlo inserendo il codice sopra nel file ed eseguendo:

perl -0pi -e 's/\\x(..)/chr hex $1/eg;s/;\n$//' oddeven.pl

3

Python 2, 138 131 byte

s="\0%s\0"%input();r=''
for i in range(len(s)-2):L,M,R=map(ord,s[i:i+3]);a=i%2and[R,L][M%2]|M or L|R;r+=chr(a*(a<127)or 32)
print r

Provalo online (contiene tutti i casi di test)

Meno golf:

def f(s):
    s="\0%s\0"%s
    r=''
    for i in range(1,len(s)-1):
        if i%2: # even (parity is changed by adding \x00 to the front)
            a=ord(s[i-1]) | ord(s[i+1])
        else:   # odd
            a=ord(s[i])
            if a%2: # odd
                a|=ord(s[i-1])
            else:   # even
                a|=ord(s[i+1])
        r+=chr(a if a<127 else 32)
    print r

Provalo online (ungolfed)

Aggiungo \x00ad entrambi i lati della stringa in modo da non dovermi preoccupare durante il bit-or-ing. Faccio un ciclo lungo i caratteri originali della stringa, eseguendo operazioni bit per bit e aggiungendoli al risultato, seguendo le regole per la parità.


Dang, sono geloso di quel |=... equivalente in PowerShell sarebbe$a=$a-bor$b
AdmBorkBork

@TimmyD In realtà non ho finito per usarlo, ma sì. È carino. Se solo Python avesse avuto a?b:cJS.
mbomb007,

Puoi sostituire se a% 2: # dispari a | = ord (s [i-1]) else: # even a | = ord (s [i + 1]) con a | = ord (s [i + 1- 2 * (a% 2)])
NoSeatbelts

@NoSeatbelts Questo è il mio codice non salvato, che verrà lasciato così com'è per motivi di leggibilità. La presentazione golfizzata è il programma principale.
mbomb007,

2

C - 101 byte

i,k;f(char*p){for(i=0;*p;++p,++i)putchar((k=i&1?*p&1?*p|p[-1]:*p|p[1]:i?p[-1]|p[1]:p[1])<127?k:' ');}

Non è nemmeno necessario verificare se si tratta dell'ultimo elemento della stringa perché le stringhe in C sono terminate con null.

Spiegazione

Piuttosto semplice:

Usa & 1 per verificare le espressioni dispari / uniformità e ternarie per sostituire if / elses. Aumentare il carattere * p per ridurre il numero di parentesi richieste.


Bella risposta - benvenuto in PPCG!
AdmBorkBork,

2

Mathematica, 152 byte

FromCharacterCode[BitOr@@Which[OddQ@Max@#2,#~Drop~{2},OddQ@#[[2]],Most@#,True,Rest@#]/._?(#>126&)->32&~MapIndexed~Partition[ToCharacterCode@#,3,1,2,0]]&

Spiegazione

ToCharacterCode@#

Converte la stringa in codici ASCII

Partition[...,3,1,2,0]

Partiziona i codici ASCII in lunghezza 3, offset 1 partizioni, con 0 imbottiti.

...~MapIndexed~...

Applica una funzione per ogni partizione.

Which[...]

If...else if... elsein Mathematica .

OddQ@Max@#2

Verifica se l'indice (n. 2) è dispari. ( Maxè per l'appiattimento); dato che l' indice Mathematica inizia da 1, ho usato OddQqui, nonEvenQ

Drop[#,{2}]

Accetta i codici ASCII dei vicini sinistro e destro.

OddQ@#[[2]]

Verifica se il codice ASCII del carattere corrispondente è dispari.

Most@#

Prende i codici ASCII del personaggio e del vicino sinistro.

Rest@#

Prende i codici ASCII del personaggio e del vicino giusto.

BitOr

Si applica o operazione.

/._?(#>126&)->32

Sostituisce tutti i numeri maggiori di 126 con 32 (spazio).

FromCharacterCode

Converte il codice ASCII in caratteri e uniscili.


Benvenuti in PPCG! Potresti aggiungere un po 'di spiegazione per le persone (come me) che non sono ben versate in Mathematica? Assicurati anche di dare un'occhiata ai Suggerimenti per il golf a Mathematica per alcuni suggerimenti. Goditi la permanenza!
AdmBorkBork,

1
Alcuni miglioramenti: accettare e restituire un elenco di caratteri anziché un oggetto stringa reale è completamente corretto e consente di risparmiare molto su tali From/ToCharacterCodefunzioni. Poi sembra che il tuo Droppossibile utilizzare la notazione infissa: #~Drop~{2}. E sembra che ti stia applicando BitOra ogni possibile output del, Whichquindi perché non applicarlo in seguito e solo una volta?
Martin Ender,

2

Rubino 133 128 108 106 byte

Jordan mi ha aiutato a salvare 20 byte e cia_rana mi ha aiutato a salvare 2 byte :)

->s{p s[-i=-1]+s.bytes.each_cons(3).map{|x,y,z|i+=1;a=i%2>0?x|z :y%2>0?y|x :y|z;a>126?' ':a.chr}*""+s[-2]}

s viene preso come stringa di input.

Esempio di output con s="Test 123 with odd characters. R@*SKA0z8d862":

"euutu133www|todddchizsscguwssr`jS{SK{z~|v66"

Spiegazione

Il codice sopra è molto illeggibile, quindi ecco una spiegazione. Il codice è un po 'confuso, ho smesso di giocare a ruby, quindi scommetto che c'è un modo più breve per farlo :)

b=s[1] # for the first character we always use the right neighbour
       # because `\0 | x` will always return x any way. 0 is the
       # left neighbour and x is the right neigbour
s.bytes.each_cons(3).with_index{|c,i| # oh boy, first we convert the string to ascii with each_byte
                                          # we then traverse the resulting array with three elements at
                                          # a time (so for example if s equals "Hello", c will be equal
                                          # to [72, 101, 108])
  if (i+1) % 2 < 1 # if the middle letter (which is considered our current letter) is even
    a = c[0] | c[2] # we use the result of binary-or of its neighbours
  else
    if c[1] % 2 > 0 # if the code of the current letter is odd
      a = c[1] | c[0] # we use the result of binary-or of itself and its left neighbour
    else
      a = c[1] | c[2] # we use the result of binary-or of itself and its right neighbour
    end
  end
  if a>126
    b<<' ' # if the result we use is greater or equal to 127 we use a space
  else
    b<<a.chr # convert the a ascii value back to a character
  end
}
p b+s[-2] # same as the first comment but now we know that x | \0 will always be x
          # this time x is the last characters left neighbour

Sono abbastanza sicuro che l'output debba essere su una riga, poiché anche l'input è.
mbomb007,

@ mbomb007 bummer, quindi devo usare printinvece di p: p
Linus

@TimmyD oh, quindi non posso stamparlo sull'output in momenti diversi?
Linus,

@TimmyD ok, quindi quanto sopra è permesso? Ora stampa tutto su una riga.
Linus,

1
Puoi scrivere come mostrato di seguito:->s{p s[-i=-1]+s.bytes.each_cons(3).map{|x,y,z|i+=1;a=i%2>0?x|z :y%2>0?y|x :y|z;a>126?' ':a.chr}*""+s[-2]}
cia_rana

1

J, 42 byte

4:u:3({.OR{:)`((2|1&{){2:OR/\|.)\0,~0,3&u:

Usa la proprietà per cui i verbi in J possono essere applicati in modo alternato usando un gerundio `per determinati avverbi come infix \.

uso

   f =: 4:u:3({.OR{:)`((2|1&{){2:OR/\|.)\0,~0,3&u:
   f 'Hello'
emmol
   f 'Hello, World!'
emmol,ww~ved
   f 'PPCG'
PSWG
   f 'Programming Puzzles and Code Golf'
rwogsmmoonpuu~meannncoooeggonl
   f 'abcdefghijklmnopqrstuvwxyz'
bcfefgnijknmno~qrsvuvw~yzz
   f '!abcdefghijklmnopqrstuvwxyz'
aaccgeggoikkomooqsswuwwyy
   f 'Test 123 with odd characters. R@*SKA0z8d862'
euutu133www|todddchizsscguwssr`jS{SK{z~|v66

Spiegazione

4:u:3({.OR{:)`((2|1&{){2:OR/\|.)\0,~0,3&u:  Input: string S
                                      3&u:  Convert each char to an ordinal
                                    0,      Prepend 0
                                 0,~        Append 0
    3                           \           For each slice of size 3
     (      )`                                For the first slice (even-index)
          {:                                    Get the tail
      {.                                        Get the head
        OR                                      Bitwise OR the head and tail
             `(                )              For the second slice (odd-index)
                             |.                 Reverse the slice
                       2:   \                   For each pair
                         OR/                      Reduce using bitwise OR
                  1&{                           Get the middle value of the slice
                2|                              Take it modulo 2
                      {                         Index into the bitwise OR pairs and select
                                              Repeat cyclically for the remaining slices
4:u:                                        Convert each ordinal back to a char and return

1

JavaScript (ES6), 125 118 114 byte

Imbarazzantemente lungo, ma charCodeAte String.fromCharCodesolo sono 29 byte. : - /

s=>[...s].map((_,i)=>String.fromCharCode((x=(C=i=>s.charCodeAt(i))((i-1)|1)|C(i+1-2*(C(i)&i&1)))>126?32:x)).join``

Come funziona

Ogni personaggio in posizione iè tradotto con la seguente formula, che copre tutte le regole contemporaneamente:

C((i - 1) | 1) | C(i + 1 - 2 * (C(i) & i & 1))

dove C(n)restituisce il codice ASCII dell'n-esimo carattere della stringa di input.

dimostrazione

let f =
    
s=>[...s].map((_,i)=>String.fromCharCode((x=(C=i=>s.charCodeAt(i))((i-1)|1)|C(i+1-2*(C(i)&i&1)))>126?32:x)).join``

console.log(f("Hello"));
console.log(f("Hello, World!"));
console.log(f("PPCG"));
console.log(f("Programming Puzzles and Code Golf"));
console.log(f("abcdefghijklmnopqrstuvwxyz"));
console.log(f("!abcdefghijklmnopqrstuvwxyz"));
console.log(f("Test 123 with odd characters. R@*SKA0z8d862"));


1

PHP, 107 97 byte

probabilmente golfable.

for(;$i<strlen($s=$argv[1]);$i++)echo chr(ord($s[$i-1+$i%2])|ord($s[$i+1-2*($i&ord($s[$i])&1)]));

1

C #, 145 byte

s=>{var r=s[1]+"";int i=1,l=s.Length,c;for(;i<l;i++){c=i>l-2?0:s[i+1];c=i%2<1?s[i-1]|c:s[i]|(s[i]%2>0?s[i-1]:c);r+=c>'~'?' ':(char)c;}return r;};

Programma completo con metodo non golfizzato e casi di test:

using System;

namespace ASCIIOddEvenCipher
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<string,string>f= s=>
            {
                var r = s[1] + "";
                int i = 1, l = s.Length, c;
                for(;i < l; i++)
                {
                    c = i>l-2 ? 0 : s[i+1];
                    c = i%2<1 ? s[i-1]|c : s[i]|(s[i]%2>0 ? s[i-1] : c);
                    r += c > '~' ? ' ' : (char)c;
                }
                return r;
            };

            //test cases:
            Console.WriteLine(f("Hello"));  //emmol
            Console.WriteLine(f("Hello, World!"));  //emmol, ww~ved
            Console.WriteLine(f("PPCG"));   //PSWG
            Console.WriteLine(f("Programming Puzzles and Code Golf"));  //r wogsmmoonpuu ~ meannncoooeggonl
            Console.WriteLine(f("abcdefghijklmnopqrstuvwxyz")); //bcfefgnijknmno~qrsvuvw~yzz
            Console.WriteLine(f("!abcdefghijklmnopqrstuvwxyz"));    //aaccgeggoikkomoo qsswuww yy
            Console.WriteLine(f("Test 123 with odd characters. R@*SKA0z8d862"));    //euutu133www|todddchizsscguwssr`jS{SK{z~|v66
        }
    }
}

Questo si è rivelato essere più lungo di quanto pensassi ...

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.