Base85 Kodlama


10

Meydan okuma

Herhangi bir ASCII yazdırılabilir karakteri içeren tek satırlık bir dizenin girişini alabilen bir program yazın ve Base85'te kodlanmış aynı dizeyi çıktılayın (big-endian kuralı kullanarak). Girişin her zaman ≤ 100 karakter olacağını varsayabilirsiniz.


Base85 Kılavuzu

  • Dört sekizli (genellikle) beş Base85 karakterine kodlanır.

  • Base85 karakter aralığı !için uve - (117 ASCII 33) z(ASCII 122).

  • Kodlamak için, dört sekizlide (32 bit sayı) sürekli olarak 85'e bölünür ve kodlanmış değerin ASCII karakterini elde etmek için geri kalana (her bölümden sonra) 33 eklersiniz. Örneğin, bu işlemin ilk uygulaması kodlanmış blokta en sağdaki karakteri üretir.

  • Dört sekizli bir kümede yalnızca boş bayt varsa, zbunun yerine kodlanır !!!!!.

  • Son blok dört sekizli'den daha kısaysa, boş baytlarla doldurulur. Kodlamadan sonra, dolgu olarak eklenen aynı sayıda karakter çıktının sonundan kaldırılır.

  • Kodlanan değerden önce <~ve sonra gelmelidir ~>.

  • Kodlanan değer boşluk içermemelidir (bu sorun için).


Örnekler

In: easy
Out: <~ARTY*~>

In: test
Out: <~FCfN8~>

In: code golf
Out: <~@rGmh+D5V/Ac~>

In: Programming Puzzles
Out: <~:i^JeEa`g%Bl7Q+:j%)1Ch7Y~>

Aşağıdaki snippet, belirli bir girdiyi Base85'e kodlar.


3
Sana yazdırılabilir ASCII girdi kısıtlamak olduğu göz önüne alındığında, neden olarak karıştı, daha sonra kullanmak byte bir eşanlamlı olarak sekizlisinin ve 7 bit bayt izin vermez.
Peter Taylor

Endianness belirtilmelidir. Bir blok [0,1,2,3], 0x0123 veya 0x3210 olarak 32 bit sayıya dönüştürülür?
edc65

@ wikipedia linkine göre edc65 big endian
Level River St

3
@steveverrill teşekkür ederim. Bu, harici bir bağlantıda değil, meydan okuma metninde olmalıdır. En azından şimdi bir yorumda
edc65

Giriş yalnızca yazdırılabilir karakterler içeriyorsa, nasıl dört boş bayt içerebilir?
Luis Mendo

Yanıtlar:


9

CJam, 43 39 35 bayt

"<~"q4/{:N4Ue]256b85b'!f+}/N,)<"~>"

CJam yorumlayıcısında çevrimiçi deneyin .

Nasıl çalışır

"<~"      e# Push that string.
q4/       e# Read all input from STDIN and split it into chunks of length 4.
{         e# For each chunk:
  :N      e#   Save it in N.
  4Ue]    e#   Right-pad it with 0's to a length of 4.
  256b85b e#   Convert from base 256 to base 85.
  '!f+    e#   Add '!' to each base-85 digit.
}/        e#
N,)       e# Push the length of the last unpadded chunk, plus 1.
<         e# Keep that many chars of the last encoded chunk.
"~>"      e# Push that string.

Giriş boşsa N,)dizeye uygulanır "<~". Yana Nbaşlangıçta tek bir karakterin tutan, çıkış doğru olacaktır.

Giriş yalnızca yazdırılabilir ASCII karakterleri içereceğinden, z ile uğraşmak veya kodlanmış parçaları 5 uzunluğa kadar doldurmak zorunda değiliz .


3
Bu çözüm şüpheli bir ASCII dizesinin Base85 sürümüne benziyor (söz konusu son başvuruya bakınız). Bekleyin ...
ojdo

1
@odjo: CJam kodunda bazı geçersiz karakterler var, en yakın aldığım bu CJam yorumlayıcı bağlantısı
schnaader

@ojdo çünkü meydan okuma sadece bu:a program that can take an input of a single-line string containing any ASCII printable characters,...
edc65

5

Python 3, 71 bayt

from base64 import*
print(a85encode(input().encode(),adobe=1).decode())

Python'da hiç golf oynamadım, bu yüzden bu muhtemelen en düşük seviyede.

3 bayt golf için @ZachGates için teşekkürler!


1
3 bayt kaydetmek input().encode()yerine kullanabilirsiniz str.encode(input()).
Zach Gates

@ZachGates Teşekkürler! Bütün bu kod çözme beni hala öldürüyor.
Dennis

2

Python 2, 193162 bayt

from struct import*
i=raw_input()
k=4-len(i)%4&3
i+='\0'*k
o=''
while i:
 b,=unpack('>I',i[-4:]);i=i[:-4]
 while b:o+=chr(b%85+33);b/=85
print'<~%s~>'%o[k:][::-1]

Bu benim ilk kod golf, bu yüzden benim yaklaşım ile ilgili bir sorun olduğundan eminim. Ayrıca sadece kütüphane işlevini çağırmak yerine base85 uygulamak istedim. :)


Bu 181 bayt. Kaydettiğinizde (IDLE kullanıyorsanız) IDLE'nin kodunuza eklediği yeni satırı kaldırmayı unutmayın. Ayrıca işlevi asla çağırmaz veya kullanıcının girdisini alamazsınız, bu nedenle çalıştırdığınızda hiçbir şey yapmaz.
Zach Gates

Bir işlev olması veya G / Ç okuması veya ne olması gerektiği konusunda emin değildim ... stdin okumalı ve stdout yazmalı mı? (Yine, daha önce hiç kod golf yapılmadı ...)
David

Programlama Bulmacaları ve Kod Golf hoş geldiniz! Giriş uzunluklarında 4 ile bölünemeyen bir sorun var gibi görünüyor (son 2 test vakası). Satır 3 okunmalı [:4+len(s)/4*4]ve çıktının sonundan hiçbir karakter kaldırılmamalıdır.
Dennis

Sorunları çözdüğüme inanıyorum (ve ne yazık ki daha uzun yaptım). Daha fazla optimize etmeye çalışıyor ...
David

Eğer ikinci açabilirsiniz whileböyle gibi birine döngü: while b:d=chr(b%85+33)+d;b/=85. printİfadenizle dize arasındaki boşluğu da kaldırabilirsiniz . Ayrıca, iletilen bağımsız değişkenler arasındaki boşluğu kaldırın s.unpack.
Zach Gates

2

Oktav, 133131 bayt

@Ojdo'ya stdin yerine argv'den girdi almamı önerdiği için teşekkürler, 2 bayt kurtardı.

function g(s) p=mod(-numel(s),4);s(end+1:end+p)=0;disp(['<~' dec2base(swapbytes(typecast(s,'uint32')),'!':'u')'(:)'(1:end-p) '~>'])

Ungolfed:

function g(s)             %// function header
p=mod(-numel(s),4);       %// number of missing chars until next multiple of 4
s(end+1:end+p)=0;         %// append p null characters to s
t=typecast(s,'uint32');   %// cast each 4 char block to uint32
u=swapbytes(t);           %// change endian-ness of uint32's
v=dec2base(u,'!':'u');    %// convert to base85
w=v'(:)'(1:end-p);        %// flatten and truncate resulting string
disp(['<~' w '~>']);      %// format and display final result

Kodu ideone'de yayınladım . Bağımsız işlev gerektirmez ve endifade etmez , ancak ideone aynı dosyada işleve ve çağıran komut dosyasına sahip olduğundan bir ayırıcı gerektirir.

Hala stdinideone üzerinde çalışmaya nasıl başlayacağımı anlayamadım. Biri bilirse, hala ilgileniyorum, bu yüzden lütfen bana bir yorum bırakın.

İdeone'den örnek çıktı :

easy
<~ARTY*~>
test
<~FCfN8~>
code golf
<~@rGmh+D5V/Ac~>
Programming Puzzles
<~:i^JeEa`g%Bl7Q+:j%)1Ch7Y~>

Neden sadece kullanmıyorsunuz argv()? Görev açıklaması, okuma girdisi gerektirmiyor gibi görünüyor stdin.
ojdo

Çok hoş! Yani yapar dec2baseOctave 36 Yukarıdaki bazlar izin?
Luis Mendo

Doc (ve hata mesajının) dediği gibi: argüman BASE2 ile 36 arasında bir sayı veya bir sembol dizisi olmalıdır . Burada ifade , taban işlevi gören 'i':'u'85 karakter dizesini genişletir !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstu.
ojdo

@ojdo Bu durumda, bir işlev yapmalı ve belki birkaç bayt kaydetmeliyim.
beher

1
@beaker Öyle. Sadece 36 sınırlaması değil, basamakların mutlaka 0 ... 9ABC olması, bu yüzden ASCII kodlarında bir sıçrama var
Luis Mendo

1

Matlab, 175 bayt

s=input('','s');m=3-mod(numel(s)-1,4);s=reshape([s zeros(1,m)]',4,[])';t=char(mod(floor(bsxfun(@rdivide,s*256.^[3:-1:0]',85.^[4:-1:0])),85)+33)';t=t(:)';['<~' t(1:end-m) '~>']

Misal:

>> s=input('','s');m=3-mod(numel(s)-1,4);s=reshape([s zeros(1,m)]',4,[])';t=char(mod(floor(bsxfun(@rdivide,s*256.^[3:-1:0]',85.^[4:-1:0])),85)+33)';t=t(:)';['<~' t(1:end-m) '~>']
code golf
ans =
<~@rGmh+D5V/Ac~>

1

PHP, 181 Bayt

foreach(str_split(bin2hex($argn),8)as$v){for($t="",$d=hexdec(str_pad($v,8,0));$d;$d=$d/85^0)$t=chr($d%85+33).$t;$r.=str_replace("!!!!!",z,substr($t,0,1+strlen($v)/2));}echo"<~$r~>";

Çevrimiçi sürüm

Expanded

foreach(str_split(bin2hex($argn),8)as$v){
    for($t="",$d=hexdec(str_pad($v,8,0));$d;$d=$d/85^0)
      $t=chr($d%85+33).$t;
    $r.=str_replace("!!!!!",z,substr($t,0,1+strlen($v)/2));
}
echo"<~$r~>";

1

Saf bash, ~ 738

Önce kodlayıcı (golf oynayan bir şey):

#!/bin/bash
# Ascii 85 encoder bash script
LANG=C

printf -v n \\%o {32..126};printf -v n "$n";printf -v m %-20sE abtnvfr;p=\<~;l()
{ q=$(($1<<24|$2<<16|$3<<8|$4));q="${n:1+(q/64#378iN)%85:1}${n:1+(q/614125)%85:1
}${n:1+(q/7225)%85:1}${n:1+(q/85)%85:1}${n:1+q%85:1}";};k() { ((${#p}>74))&&ech\
o "${p:0:75}" && p=${p:75};};while IFS= read -rd '' -n 1 q;do [ "$q" ]&&{ print\
f -v q "%q" "$q";case ${#q} in 1|2)q=${n%$q*};o+=($((${#q}+32)));;7)q=${q#*\'\\}
o+=($((8#${q%\'})));;5)q=${q#*\'\\};q=${m%${q%\'}*};o+=($((${#q}+07)));;esac;}||
o+=(0);((${#o[@]}>3))&&{ [ "${o[*]}" = "0 0 0 0" ]&& q=z|| l ${o[@]};p+="${q}";k
o=(); };done;[ "$o" ]&&{ f=0;for((;${#o[@]}<4;)){ o+=(0);((f++));};((f==0))&&[ \
"${o[*]}" = "0 0 0 0" ]&&q=z||l ${o[@]};p+="${q:0:5-f}";};p+="~>";k;[ "$p" ]&&e\
cho "$p"

Testler:

for word in easy test code\ golf Programming\ Puzzles ;do
    printf "%-24s" "$word:"
    ./enc85.sh < <(printf "$word")
  done
easy:                   <~ARTY*~>
test:                   <~FCfN8~>
code golf:              <~@rGmh+D5V/Ac~>
Programming Puzzles:    <~:i^JeEa`g%Bl7Q+:j%)1Ch7Y~>

ve şimdi kod çözücü:

#!/bin/bash
# Ascii 85 decoder bash script
LANG=C

printf -v n "\%o" {33..117};printf -v n "$n";o=1 k=1;j(){ read -r q||o=;[ "$q" \
]&&[ -z "${q//*<~*}" ]&&((k))&&k= q="${q#*<~}";m+="$q";m="${m%~>*}";};l(){ r=;f\
or((i=0;i<${#1};i++)){ s="${1:i:1}";case "$s" in "*"|\\|\?)s=\\${s};;esac;s="${\
n%${s}*}";((r+=${#s}*(85**(4-i))));};printf -v p "\%03o" $((r>>24)) $((r>>16&255
)) $((r>>8&255)) $((r&255));};for((;(o+${#m})>0;)){ [ "$m" ] || j;while [ "${m:0
:1}" = "z" ];do m=${m:1};printf "\0\0\0\0";done;if [ ${#m} -ge 5 ];then q="${m:0
:5}";m=${m:5};l "$q";printf "$p";elif ((o));then j;elif [ "${m##z*}" ];then pri\
ntf -v t %$((5-${#m}))s;l "$m${t// /u}";printf "${p:0:16-4*${#t}}";m=;fi;}

Bunu kopyalayın enc85.shve dec85.sh, chmod +x {enc,dec}85.shve ardından:

./enc85.sh <<<'Hello world!'
<~87cURD]j7BEbo80$3~>
./dec85.sh <<<'<~87cURD]j7BEbo80$3~>'
Hello world!

Ancak daha güçlü bir test yapabilirsiniz:

ls -ltr --color $HOME/* | gzip | ./enc85.sh | ./dec85.sh | gunzip

724 karaktere düşürüldü:

printf -v n \\%o {32..126};printf -v n "$n";printf -v m %-20sE abtnvfr;p=\<~
l(){ q=$(($1<<24|$2<<16|$3<<8|$4))
q="${n:1+(q/64#378iN)%85:1}${n:1+(q/614125)%85:1}${n:1+(q/7225)%85:1}${n:1+(q/85)%85:1}${n:1+q%85:1}"
};k() { ((${#p}>74))&&echo "${p:0:75}" && p=${p:75};};while IFS= read -rd '' -n 1 q;do [ "$q" ]&&{
printf -v q "%q" "$q";case ${#q} in 1|2)q=${n%$q*};o+=($((${#q}+32)));;7)q=${q#*\'\\}
o+=($((8#${q%\'})));;5)q=${q#*\'\\};q=${m%${q%\'}*};o+=($((${#q}+07)));;esac;}||o+=(0)
((${#o[@]}>3))&&{ [ "${o[*]}" = "0 0 0 0" ]&&q=z||l ${o[@]};p+="${q}";k
o=();};done;[ "$o" ]&&{ f=0;for((;${#o[@]}<4;)){ o+=(0);((f++));}
((f==0))&&[ "${o[*]}" = "0 0 0 0" ]&&q=z||l ${o[@]};p+="${q:0:5-f}";};p+="~>";k;[ "$p" ]&&echo "$p"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.