Base85 एनकोडिंग


10

चुनौती

एक प्रोग्राम लिखें जो किसी भी ASCII प्रिंट करने योग्य वर्णों वाली एकल-लाइन स्ट्रिंग का इनपुट ले सकता है, और उसी स्ट्रिंग को Base85 में एन्कोडेड (बड़े-एंडियन कन्वेंशन का उपयोग करके) आउटपुट करता है । आप मान सकते हैं कि इनपुट हमेशा input 100 अक्षर का होगा।


बेस 85 के लिए एक गाइड

  • चार ओकटेट्स को (आमतौर पर) पांच बेस 85 अक्षरों में एन्कोड किया गया है।

  • Base85 पात्रों से लेकर !के लिए uऔर - (117 33 ASCII) z(ASCII 122)।

  • सांकेतिक शब्दों में बदलना करने के लिए, आप लगातार चार अष्टक (32-बिट संख्या) पर 85 से विभाजन करते हैं, और एन्कोडेड मान के लिए ASCII वर्ण प्राप्त करने के लिए शेष 33 (प्रत्येक विभाजन के बाद) जोड़ते हैं। उदाहरण के लिए, इस प्रक्रिया का पहला अनुप्रयोग एन्कोडेड ब्लॉक में सबसे सही वर्ण बनाता है।

  • यदि चार ऑक्टेट के सेट में केवल नल बाइट्स होते हैं, तो वे zइसके बजाय एन्कोडेड होते हैं !!!!!

  • यदि अंतिम ब्लॉक चार ओकटेट्स से कम है, तो यह अशक्त बाइट्स के साथ गद्देदार है। एन्कोडिंग के बाद, उतने ही वर्ण जिन्हें पैडिंग के रूप में जोड़ा गया था, आउटपुट के अंत से हटा दिए जाते हैं।

  • एन्कोडेड वैल्यू से पहले <~और उसके बाद होना चाहिए ~>

  • एन्कोडेड मान में कोई व्हॉट्सएप नहीं होना चाहिए (इस चुनौती के लिए)।


उदाहरण

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

निम्नलिखित स्निपेट बेस85 को दिए गए इनपुट को एन्कोड करेगा।


3
मैं उलझन में हूं कि क्यों, यह देखते हुए कि आपने मुद्रण योग्य ASCII के लिए इनपुट को प्रतिबंधित किया है, तो आप ऑक्टेट के पर्याय के रूप में बाइट का उपयोग करते हैं और 7-बिट बाइट्स की अनुमति नहीं देते हैं।
पीटर टेलर

धीरज निर्दिष्ट किया जाना चाहिए। एक ब्लॉक [0,1,2,3] को 32 बिट संख्या 0x0123 या 0x3210 के रूप में परिवर्तित किया जाता है?
edc65

विकिपीडिया लिंक के अनुसार @ edc65 बिग एंडियन
लेवल रिवर सेंट

3
@steveverrill धन्यवाद। यह चुनौती पाठ में होना चाहिए, न कि किसी बाहरी लिंक में। कम से कम अब यह एक टिप्पणी में है
edc65

यदि इनपुट में केवल मुद्रण योग्य वर्ण हो सकते हैं, तो इसमें चार नल बाइट कैसे हो सकते हैं?
लुइस मेंडो

जवाबों:


9

सीजेएम, 43 39 35 बाइट्स

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

CJam दुभाषिया में इसे ऑनलाइन आज़माएं ।

यह काम किस प्रकार करता है

"<~"      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.

यदि इनपुट खाली था, N,)तो स्ट्रिंग पर लागू होगा "<~"। जबसेN शुरू में एकल वर्ण रखता है, आउटपुट सही होगा।

हमें निपटना नहीं है z या पैड से एन्कोडेड चंक्स से 5 की लंबाई तक , क्योंकि इनपुट में केवल मुद्रण योग्य ASCII वर्ण होंगे।


3
यह समाधान संदिग्ध रूप से ASCII स्ट्रिंग के बेस 85 संस्करण की तरह दिखता है (प्रश्न में अंतिम उदाहरण)। रुकिए ...
ojdo

1
@odjo: CJam कोड में कुछ अमान्य अक्षर हैं, मुझे जो सबसे करीबी मिला है वह है CJam दुभाषिया लिंक
schnaader

@ बसो क्योंकि चुनौती सिर्फ यह है:a program that can take an input of a single-line string containing any ASCII printable characters,...
edc65

5

पायथन 3, 71 बाइट्स

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

मैंने पायथन में कभी गोल्फ नहीं खेला है, इसलिए यह शायद उप-इष्टतम है।

3 बाइट बंद करने के लिए @ZachGates का धन्यवाद!


1
आप 3 बाइट्स को बचाने के input().encode()बजाय उपयोग कर सकते हैं str.encode(input())
जैच गेट्स

@ZachGates धन्यवाद! सभी कि एन / डिकोडिंग अभी भी मुझे मार रहा है।
डेनिस

2

पायथन 2, 193 162 बाइट्स

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]

यह मेरा पहला कोड गोल्फ है, इसलिए मुझे यकीन है कि मेरे दृष्टिकोण में कुछ गड़बड़ है। मैं भी वास्तव में बेस फंक्शन लागू करना चाहता था बजाय सिर्फ लाइब्रेरी फंक्शन को कॉल करना। :)


यह 181 बाइट्स है। जब आप सहेजते हैं तो IDLE आपके कोड में जुड़ने वाली नई पंक्ति को हटाना न भूलें (यदि आप IDLE का उपयोग कर रहे हैं)। आप कभी भी फ़ंक्शन को कॉल नहीं करते हैं, या उपयोगकर्ता का इनपुट प्राप्त नहीं करते हैं, इसलिए जब आप इसे चलाते हैं तो यह कुछ भी नहीं करता है।
जैच गेट्स

निश्चित नहीं था कि यह एक फ़ंक्शन होना चाहिए या I / O या क्या पढ़ना चाहिए ... क्या इसे स्टडिन और प्रिंट स्टडआउट पढ़ना चाहिए? (फिर, कोड गोल्फ से पहले कभी नहीं किया ...)
डेविड

प्रोग्रामिंग पहेलियाँ और कोड गोल्फ में आपका स्वागत है! ऐसा लगता है कि इनपुट लंबाई के साथ एक समस्या है जो 4 (पिछले 2 परीक्षण मामलों) से विभाज्य नहीं है। पंक्ति 3 को पढ़ना चाहिए [:4+len(s)/4*4]और आउटपुट के अंत से कोई वर्ण नहीं हटाया जाता है।
डेनिस

मेरा मानना ​​है कि मैंने मुद्दे तय कर दिए हैं (और दुर्भाग्य से इसे लंबा कर दिया गया है)। अधिक अनुकूलन करने की कोशिश कर रहा है ...
डेविड

आप अपने दूसरे whileलूप को इस तरह से एक में बदल सकते हैं while b:d=chr(b%85+33)+d;b/=85:। आप अपने printस्टेटमेंट और स्ट्रिंग के बीच की जगह को भी हटा सकते हैं । इसके अतिरिक्त, दिए गए तर्कों के बीच के स्थान को हटा दें s.unpack
जैच गेट्स

2

ऑक्टेव, 133 131 बाइट्स

सुझाव के लिए @ योजना के लिए धन्यवाद, मैं स्टड के बजाय argv से इनपुट लेता हूं, मुझे 2 बाइट्स बचा रहा है।

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

मैंने ideone पर कोड पोस्ट किया है । स्टैंडअलोन फ़ंक्शन की आवश्यकता नहीं है और endबयान की आवश्यकता होती है , लेकिन क्योंकि आइडोन में फ़ंक्शन और कॉलिंग स्क्रिप्ट एक ही फ़ाइल में होती है, इसके लिए एक विभाजक की आवश्यकता होती है।

मैं अभी भी यह पता लगाने में सक्षम नहीं है कि stdinआइडोन पर काम कैसे किया जाए। अगर किसी को पता है, मुझे अभी भी दिलचस्पी है, तो कृपया मुझे एक टिप्पणी दें।

Ideone से नमूना उत्पादन :

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

सिर्फ उपयोग क्यों नहीं argv()? कार्य विवरण से पढ़ने के इनपुट की आवश्यकता नहीं लगती है stdin
ओजडो

बहुत अच्छा! तो क्या dec2baseऑक्टेव में 36 से ऊपर के अड्डों की अनुमति है?
लुइस मेंडू

जैसा कि डॉक्टर (और त्रुटि संदेश) कहते हैं: तर्क BASE2 और 36 के बीच की संख्या या प्रतीकों का एक स्ट्रिंग होना चाहिए । यहाँ, अभिव्यक्ति 'i':'u'85 अक्षर स्ट्रिंग का विस्तार !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuकरती है जो आधार के रूप में कार्य करती है।
ओजडो

@ यदि यह मामला है तो मुझे इसे एक समारोह बनाना चाहिए और शायद कुछ बाइट्स बचाए।
बीकर

1
@ बीकर यह करता है। न केवल सीमा तक 36, लेकिन यह तथ्य कि अंक जरूरी हैं 0 ... 9ABC, इसलिए ASCII कोड में एक छलांग है
लुइस मेंडो

1

मतलाब, 175 बाइट्स

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) '~>']

उदाहरण:

>> 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 बाइट्स

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~>";

ऑनलाइन संस्करण

विस्तारित

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

शुद्ध बैश, ~ 738

एनकोडर पहले (कुछ गोल्फ हुआ):

#!/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"

टेस्ट:

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

और डिकोडर अब:

#!/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;}

इस कॉपी enc85.shऔर dec85.sh, chmod +x {enc,dec}85.shहै, तो:

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

लेकिन आप कुछ मजबूत परीक्षण कर सकते हैं:

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

724 चार्ट में घटाया गया:

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"
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.