ASCII字符混杂


24

编写一个程序,将包含可打印字符(ASCII 20-7E)和n[2,16]中的整数的字符串作为输入,并对字符串进行以下修改。

  • 字符串中的每个字符都将转换为其ASCII码(给出的示例为十六进制,但基数10也可以接受)。
  • ASCII码将转换为基数n并串联在一起。
  • 新字符串将每隔一个字符分割一次。如果有奇数个字符,则最后一个字符将被完全删除。
  • 打印的ASCII代码(以16为基数)被转换回其字符,而非打印的ASCII代码被删除。
  • 结果字符串被打印出来。

测试用例

输入项

Hello, World!
6

脚步

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

该程序的输出为 E001R"31$E


这是代码高尔夫球,因此适用标准规则。以字节为单位的最短代码获胜。


此编码算法可用于发送秘密消息!
Kritixi Lithos

一定要这样做!
anOKsquirrel

@ΚριτικσιΛίθος程序对每个可能的输入字符串均有效,但并非每个输出字符串都是唯一的。例如,在base中7,字符串J将通过J-> 50-> 101-> 10->步骤(no output),字符串K或也将通过L
Arcturus

就像@Eridan所说的,这是有损加密,因为奇数序列会丢失最后一个字符。尽管我确定对无知的观察者来说,这可能是一种愚蠢的交流方式:)
DoctorHeckle

1
步骤1令人困惑-无需将char转换为十六进制-在示例中:H是ASCII 72(十进制)或48(十六进制),但是我需要的是200(基数6)。在我看来,示例中的所有第2行都是无用的和令人困惑的
edc65

Answers:





2

CJam,24个字节

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

请注意,有一个DEL字符(0x7F的)之间',。在CJam解释器中在线尝试。

怎么运行的

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.

那DEL字符呢?看来您已经解决了这个问题,但是在您的解释中我看不到它!
wizzwizz4 2015年

StackExchange过滤不可打印的字符。DEL字符仅出现在此永久链接中,即使在该链接中也不可见。
丹尼斯

我的意思是... Delete是控制字符,但不是前32个字符之一。对于不熟悉ASCII的人,它是字符编号127,0x7F。
wizzwizz4 2015年

我不确定我是否理解您的问题。您是否想知道如何从输出中过滤出来?
丹尼斯

是。您的代码说明似乎并未说明如何DEL从输出中过滤字符。
wizzwizz4 2015年

2

JavaScript(ES6),137 147

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


+1x=>x>=
Ypnypn

我想你可以用节省一些字节[for(z of ...)if(...)...],而不是map(...).filter(...)
Ypnypn

@Ypnypn我没有找到一种使用您的提示的方法(除了使用ES7的数组理解之外),但是您让我重新考虑了这一切。谢谢。我希望即使您x=>x>=已经离开也能保持+1
edc65

1
使用ES7有什么问题?
Ypnypn

1
@Ypnypn我更喜欢这样的答案,即使在<troll on> Chrome </ troll off>之类的javascript引擎下也可以使用
edc65 2015年

1

朱莉娅118字节

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

取消高尔夫:

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个字节

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

如果允许功能:

Mathematica,112个字节

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

1

TeaScript,23个字节

TeaScript是用于高尔夫的JavaScript

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

相对简单明了但令人愉快的简短。我可能可以和更多的操作员一起打高尔夫球。其他一些新功能也可以用来减少一些字节。

取消&&说明

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

1
我相信这是23个字符(29 个字节)长。
Cristian Lupascu 2015年

@ w0lf这将是UTF-8编码,但是因为所有字符都小于256,所以我们可以安全地将它们视为一个字节
Downgoat 2015年


1

Python 2,174字节

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

在这里尝试

并不是真正的最佳工具。由于Python没有转换为任意基数的函数,因此我必须实现自己的函数。至少这很有趣-特别是找到了一个比[]短的数字表达式"0123456789ABCDEF"[n%b]。为了一次遍历两个字符,我发现while循环比功能方法略短。

完整程序为181个字节:

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字节

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

我编写了一个函数k,该函数采用字符串s和整数n作为输入。例如:

k('Hello, World!',6)

 E001R"31$E

我必须解决的最烦人的事情是在转换为基数n时出现零。将它们从要在第二个字符之后拆分的数组中取出要花费很多字节。不知道是否可以使用这种方法保存更多的字节。


0

PHP-286字节

将字符串放入$s,将整数放入$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)))));?>

将值传递给GET["s"]

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.