ASCII-Zeichen-Durcheinander


24

Ein Programm schreiben , die einen String aus druckbaren Zeichen (ASCII 20-7E) und eine ganze Zahl als ihren Eingang nimmt nin [2,16] , und führt die folgende Modifikation an der Schnur.

  • Jedes Zeichen in der Zeichenkette in ihrem ASCII-Code umgesetzt (die angegebenen Beispiele sind in hexadezimal, wenn Basis 10 auch annehmbar ist).
  • Die ASCII - Codes werden auf Basis umgewandelt nund miteinander verkettet.
  • Die neue Zeichenfolge wird in alle anderen Zeichen aufgeteilt. Wenn es eine ungerade Anzahl von Zeichen sind, dann wird das letzte Zeichen vollständig entfernt.
  • Druck-ASCII-Codes (in Basis 16) werden zurück in ihre Zeichen konvertiert, während nicht druckbare ASCII-Codes entfernt werden.
  • Die resultierende Zeichenfolge wird gedruckt.

Testfall

Eingang

Hello, World!
6

Schritte

Hello, World!
48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21
2002453003003031125222330331030024453
20 02 45 30 03 00 30 31 12 52 22 33 03 31 03 00 24 45

Die Ausgabe dieses Programms ist E001R"31$E.


Dies ist Codegolf, daher gelten die Standardregeln. Kürzester Code in Bytes gewinnt.


Dieser Kodierungsalgorithmus kann nützlich sein, um geheime Nachrichten zu senden!
Kritixi Lithos

Muss ich irgendwann machen!
anOKsquirrel

@ ΚριτικσιΛίθος , während das Programm für jede mögliche Eingabezeichenfolge funktioniert nicht jede Ausgabe - String ist einzigartig. In base würde 7die Zeichenfolge beispielsweise Jdie Schritte J-> 50-> 101-> 10-> durchlaufen (no output), ebenso wie die Zeichenfolge Koder L.
Arcturus

Wie @Eridan sagte, ist dies eine verlustbehaftete Verschlüsselung, da bei ungeraden Sequenzen das letzte Zeichen entfernt wird. Obwohl ich sicher , die Unwissenden Beobachter bin es könnte eine snarky Art der Kommunikation :) sein
DoctorHeckle

1
Schritt 1 ist verwirrend - keine Notwendigkeit, Zeichen zu hexadezimal konvertieren - im Beispiel: HASCII 72 (dezimal) oder 48 (hex), aber was ich brauche , ist 200 (Basis 6). Die ganze Zeile 2 im Beispiel ist meiner Meinung nach nutzlos und verwirrend
edc65

Antworten:




3

Bash + gemeinsame Linux-Utils, 118

printf %s "$1"|xxd -p|sed -r "s/../\U& /g;y/ /n/;s/^/dc -e$2o16i/e;s/../& /g;s/ .$//;"|xxd -rp|sed 's/[^[:print:]]//g'

Ich denke , man könnte verkürzen printf %s "$1"in echo -n "$1"2 Bytes zu speichern
Aaron

@Aaron Das funktioniert, bis die Eingabezeichenfolge ist -e. Versuchenecho -n "-e"
Digital Trauma

Verdammt, schön gesehen!
Aaron

2

CJam, 24 Bytes

l:irifbe_2/{Gbc',32>&}/

Beachten Sie, dass sich zwischen 'und ein DEL-Zeichen (0x7F) befindet ,. Versuchen Sie es online in dem CJam Dolmetscher .

Wie es funktioniert

l:i                     Read a line from STDIN and cast each char to integer. 
   ri                   Read another integer (base) from STDIN.
     fb                 Convert each integer from line 1 to that base.
       e_2/             Flatten and split into chunks of length 2.
                        If the last chunk has only one element, it will get
                        converted into a control character, which will be
                        removed later.
          {         }/  For each digit pair:
           Gb             Convert the pair from base 16 to integer.
             c            Cast to character.
              ',          Push the string of ASCII characters up to '~'.
                32>       Remove the first 32 (control characters).
                   &      Intersect.

Was ist mit dem DEL-Zeichen ...? Es sieht so aus, als hättest du das umgangen, aber ich kann es in deiner Erklärung nicht sehen!
wizzwizz4

StackExchange filtert nicht druckbare Zeichen. Das DEL-Zeichen ist nur im Permalink vorhanden und auch dort nicht sichtbar.
Dennis

Ich meine ... Delete ist ein Steuerzeichen, aber keines der ersten 32 Zeichen. Es handelt sich um das Zeichen 127 (0x7F) für Personen, die mit ASCII nicht vertraut sind.
wizzwizz4

Ich bin mir nicht sicher, ob ich deine Frage verstanden habe. Fragen Sie sich, wie ich es aus der Ausgabe filtern?
Dennis

Ja. Ihre Code-Erklärung scheint nicht zu sagen, wie Sie das DELZeichen aus der Ausgabe filtern .
wizzwizz4

2

JavaScript (ES6), 137 147

Verwenden der ausführlichsten in JavaScript verfügbaren Funktionen

f=(s,b)=>alert(s.replace(/./g,x=>x.charCodeAt().toString(b)).match(/../g).map(x=>(x=String.fromCharCode('0x'+x))<='~'&x>' '?x:'').join``)

// Just for test purpose, redefine alert()
alert=x=>document.write('<pre>'+x+'</pre>')

f('Hello, World!',6)
f('PORK',3)


+1 fürx=>x>=
Ypnypn

Ich denke, Sie können einige Bytes sparen, indem Sie [for(z of ...)if(...)...]anstelle vonmap(...).filter(...)
Ypnypn

@Ypnypn Ich habe keine Möglichkeit gefunden, Ihren Hinweis zu verwenden (abgesehen von Array-Verständnis, das ES7 ist), aber Sie haben mich gedrängt, alles zu überdenken. Danke. Ich hoffe, du behältst deine +1, auch wenn x=>x>=sie weg ist
edc65

1
Was ist los mit ES7 mit?
Ypnypn

1
@Ypnypn ziehe ich eine Antwort , die auch mit subpar Javascript Engines <Troll auf> wie Chrome </ Troll off> arbeiten kann
edc65

1

Julia, 118 Bytes

f(s,n)=join(map(i->(c=string(Char(parse(Int,i,16))))^isprint(c),matchall(r"..",join(map(i->base(n,Int(i)),[s...])))))

Ungolfed:

function f(s::AbstractString, n::Integer)
    # Construct an array of ASCII codes in base n
    v = map(i -> base(n, Int(i)), [s...])

    # Join into a string and get all pairs, truncating
    # to an even length
    m = matchall(r"..", join(v))

    # Parse each pair as an integer in base 16, get the
    # character associated with that code point, convert
    # to a string, and include if it's printable
    x = map(i -> (c = string(Char(parse(Int, i, 16)))^isprint(c), m)

    # Join as a string and return
    return join(x)
end

1

Mathematica, 134 Bytes

Print@FromCharacterCode@Select[#~FromDigits~16&/@StringPartition[""<>ToCharacterCode@InputString[]~IntegerString~Input[],2],31<#<127&]

Wird eine Funktion erlaubt:

Mathematica, 112 Bytes

FromCharacterCode@Select[#~FromDigits~16&/@StringPartition[""<>ToCharacterCode@#~IntegerString~#2,2],31<#<127&]&

1

TeaScript, 23 Bytes

TeaScript ist JavaScript zum Golfen

£lc¡T(y©K(2)ßC(P(l,16±µ

Relativ unkompliziert, aber angenehm kurz. Ich kann wahrscheinlich noch ein paar Charaktere mit ein paar weiteren Operatoren spielen. Einige weitere neue Funktionen könnten auch in der Lage sein, um abgeholzt einige Bytes verwendet werden.

Ungolfed && Erklärung

x.l(#
    l.c().T(y)
).K(2)
.m(#
    C(
      P(l,16)
    )
).j``

1
Ich glaube, das ist 23 Zeichen (29 Bytes ) lang.
Cristian Lupascu

@ w0lf Das wäre mit UTF-8-Codierung, aber da alle Zeichen weniger als 256 sind, können wir sie sicher als ein Byte zählen
Downgoat

1

Ruby 92

->s,n{o=''
s.chars.map{|x|x.ord.to_s n}.join.scan(/../).map{|x|x>?2&&x<?8&&o<<x.to_i(16)}
o}

Online Test hier .


1

Python 2, 174 Bytes

def J(a,b,i=0):
 h=r=''
 B=lambda n,b:n*'x'and B(n/b,b)+chr(48+n%b+7*(n%b>9))
 for c in a:h+=B(ord(c),b)
 while i<len(h):v=int(h[i:i+2],16);r+=chr(v)*(31<v<127);i+=2
 print r

Probieren Sie es hier aus

Nicht wirklich das beste Werkzeug für den Job. Da Python keine Funktion zum Konvertieren in eine beliebige Basis hat, musste ich meine eigene implementieren. Zumindest hat das Spaß gemacht - besonders, wenn man einen [geringfügig] kürzeren Ausdruck für die Ziffern gefunden hat als "0123456789ABCDEF"[n%b]. Beim Durchlaufen von jeweils zwei Zeichen stellte ich fest, dass eine whileSchleife etwas kürzer war als ein funktionaler Ansatz.

181 Bytes als volles Programm:

B=lambda n,b:n*'x'and B(n/b,b)+chr(48+n%b+7*(n%b>9))
a=raw_input()
b=input()
h=r=''
for c in a:h+=B(ord(c),b)
i=0
while i<len(h):v=int(h[i:i+2],16);r+=chr(v)*(31<v<127);i+=2
print r

0

MATLAB, 103 Bytes

function k(s,n),b=dec2base(s,n)';b(~cumsum(b-'0',1))='';c=base2dec(textscan(b,'%2c'),16)';char(c(c>31))

Ich habe eine Funktion k geschrieben , die einen String s und eine ganze Zahl n als Eingabe nimmt. z.B:

k('Hello, World!',6)

gibt

 E001R"31$E

Das Ärgerlichste, das ich umgehen musste, ist, dass beim Konvertieren zur Basis n führende Nullen angezeigt werden . Diese aus dem Array herauszuholen, das nach jedem zweiten Zeichen aufgeteilt werden sollte, kostete eine ganze Menge Bytes. Nicht sicher, ob es möglich ist, weitere Bytes mit diesem Ansatz zu speichern.


0

PHP - 286 Bytes

Geben Sie die Zeichenfolge $sund die Ganzzahl ein $b.

<?php $s=$_GET["s"];$b;$m="array_map";echo implode($m(function($v){return ctype_print($v)?$v:"";},$m("chr",$m("hexdec",str_split(strlen(implode($a=$m(function($v){global$b;return base_convert($v,16,$b);},$m("dechex",$m("ord",str_split($s))))))%2==1?substr(implode($a),0,-1):$a,2)))));?>

Übergeben Sie den Wert an GET["s"].

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.