Desordem de caracteres ASCII


24

Escreva um programa que tenha como entrada uma sequência composta por caracteres imprimíveis (ASCII 20-7E) e um número inteiro nem [2,16] e execute a seguinte modificação na sequência.

  • Cada caractere na string é convertido em seu código ASCII (os exemplos dados são em hexadecimal, embora a base 10 também seja aceitável).
  • Os códigos ASCII são convertidos em base ne são concatenados juntos.
  • A nova string é dividida em todos os outros caracteres. Se houver um número ímpar de caracteres, o último caractere será removido completamente.
  • Os códigos ASCII de impressão (na base 16) são convertidos novamente em seus caracteres, enquanto os códigos ASCII que não são de impressão são removidos.
  • A sequência resultante é impressa.

Caso de teste

Entrada

Hello, World!
6

Passos

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

A saída deste programa é E001R"31$E.


Isso é código de golfe, então as regras padrão se aplicam. O menor código em bytes vence.


Este algoritmo de codificação pode ser útil para enviar mensagens secretas!
Kritixi Lithos

Tenho que fazer isso algum dia!
Anoksquirrel 4/11/15

@ ΚριτικσιΛίθος enquanto o programa funciona para todas as sequências de entrada possíveis, nem todas as sequências de saída são únicas. Por exemplo, na base 7, a sequência Jpassaria pelas etapas J-> 50-> 101-> 10-> (no output), assim como a sequência Kou L.
Arcturus

Como @Eridan disse, esta é uma criptografia com perdas, pois sequências ímpares são cortadas no último caractere. Embora eu tenha certeza para o observador ignorante, isso pode ser uma maneira sarcástica de se comunicar :) #
457

11
A etapa 1 é confusa - não é necessário converter caracteres em hexadecimal - no exemplo: Hé ASCII 72 (decimal) ou 48 (hex), mas o que eu preciso é de 200 (base 6). Toda a linha 2 no exemplo é inútil e confuso na minha opinião
edc65

Respostas:




3

Bash + utilitários linux comuns, 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'

Eu acho que você poderia encurtar printf %s "$1"para echo -n "$1"salvar 2 bytes
Aaron

@ Aaron Isso funciona até que a string de entrada seja -e. Tenteecho -n "-e"
Digital Trauma

Porra, bem manchado!
Aaron

2

CJam, 24 bytes

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

Observe que há um caractere DEL (0x7F) entre 'e ,. Experimente online no intérprete CJam .

Como funciona

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.

E o personagem DEL ...? Parece que você já trabalhou nisso, mas não consigo ver na sua explicação!
Wizzwizz4

O StackExchange filtra caracteres não imprimíveis. O caractere DEL está presente apenas no link permanente e é invisível até lá.
Dennis #

Quero dizer ... Excluir é um caractere de controle, mas não é um dos primeiros 32 caracteres. É o número de caractere 127, 0x7F, para pessoas que não estão familiarizadas com o ASCII.
wizzwizz4

Não sei se entendi sua pergunta. Você está se perguntando como eu filtrá-lo da saída?
Dennis

Sim. Sua explicação do código não parece dizer como você filtra o DELcaractere da saída.
Wizzwizz4

2

JavaScript (ES6), 137 147

Usando as funções mais detalhadas disponíveis em JavaScript

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 parax=>x>=
Ypnypn 4/11/15

Eu acho que você pode salvar alguns bytes usando em [for(z of ...)if(...)...]vez demap(...).filter(...)
Ypnypn 4/15

@Ypnypn Eu não encontrei uma maneira de usar sua dica (além de compreender a matriz que é o ES7), mas você me pressionou a repensar tudo. THX. Eu espero que você vai manter seu +1 mesmo se x=>x>=passou
edc65

11
O que há de errado em usar o ES7?
Ypnypn

11
@Ypnypn eu prefiro uma resposta que pode funcionar mesmo com motores subpar javascript <trolls em> como o Chrome </ trolls off>
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&]

Se uma função é permitida:

Mathematica, 112 bytes

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

1

TeaScript, 23 bytes

TeaScript é JavaScript para jogar golfe

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

Relativamente simples, mas deliciosamente curto. Provavelmente posso jogar mais alguns personagens com mais operadores. Alguns outros novos recursos também podem ser usados ​​para reduzir alguns bytes.

Ungolfed && Explicação

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

11
Eu acredito que isso tenha 23 caracteres (29 bytes ).
Cristian Lupascu 5/11

@ w0lf Isso seria com codificação UTF-8, mas porque todos os personagens são menos de 256 nós podemos seguramente contá-los como um byte
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}

Teste online aqui .


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

Experimente aqui

Não é realmente a melhor ferramenta para o trabalho. Como o Python não tem função de conversão em base arbitrária, eu tive que implementar a minha própria. Isso foi divertido, pelo menos - particularmente encontrar uma expressão [marginalmente mais curta] para os dígitos do que "0123456789ABCDEF"[n%b]. Para iterar mais de dois caracteres por vez, descobri que um whileloop era um pouco menor que uma abordagem funcional.

181 bytes como um programa completo:

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

Eu escrevi uma função k que leva uma string s e um inteiro n como entrada. por exemplo:

k('Hello, World!',6)

 E001R"31$E

A coisa mais irritante que eu tive para contornar é o aparecimento de zeros na conversão para a base n . Tirar esses dados da matriz que seria dividida após cada segundo caractere custa muitos bytes. Não tenho certeza se é possível salvar mais bytes usando essa abordagem.


0

PHP - 286 bytes

Coloque a string $se o número inteiro em $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)))));?>

Passe o valor para GET["s"].

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.