Base64 decode data: Difference between revisions

added RPL
(added RPL)
 
(4 intermediate revisions by 4 users not shown)
Line 554:
* but the module is currently in flux, so the implementation is included "inline" here.
*/
module Base64 {
{
@Inject Console console;
void run() {
{
String orig = \|VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIH\
|lvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g=
Line 566 ⟶ 564:
assert text == orig;
console.print($"base64={text}, bytes={bytes}");
}
 
static Byte[] read(Iterator<Char> stream) {
{
Int charLen = 0;
charLen := stream.knownSize();
Line 575 ⟶ 572:
Byte prevBits = 0;
Int prevCount = 0;
while (Char ch := stream.next()) {
if (Byte newBits := isBase64(ch, assertTrash=True)) {
{
if (Byte newBits := isBase64if (ch,prevCount assertTrash=True)= 0) {
{
if (prevCount == 0)
{
prevBits = newBits;
prevCount = 6;
} else }{
else
{
byteBuf.add((prevBits << 8-prevCount) | (newBits >> prevCount-2));
prevBits = newBits;
prevCount -= 2;
}
}
}
{}
 
return byteBuf.freeze(True);
}
 
static void write(Byte[] value, Appender<Char> stream, Boolean pad=False, Int? lineLength=Null) {
{lineLength ?:= Int.MaxValue;
lineLength ?:= Int.maxvalue;
 
Int lineOffset = 0;
Line 606 ⟶ 597:
Int byteOffset = 0;
Int byteLength = value.size;
while (True) {
{
// glue together the next six bits, which will create one character of output
Byte sixBits;
if (byteOffset >= byteLength) {
if (prevCount == 0) {
if (prevCount == 0)
{
break;
}
sixBits = prevByte << 6 - prevCount;
prevCount = 0;
} else if (prevCount }== 6) {
else if (prevCount == 6)
{
sixBits = prevByte << 6 - prevCount;
prevCount = 0;
} else }{
else
{
Byte nextByte = value[byteOffset++];
sixBits = (prevByte << 6 - prevCount) | (nextByte >> 2 + prevCount);
prevByte = nextByte;
prevCount += 2;
}
 
if (lineOffset >= lineLength) {
{
stream.add('\r').add('\n');
totalChars += lineOffset;
lineOffset = 0;
}
 
stream.add(base64(sixBits & 0b111111));
++lineOffset;
}
 
if (pad) {
{
totalChars += lineOffset;
for (Int i = 0, Int padCount = 4 - (totalChars & 0b11) & 0b11; i < padCount; ++i) {
if (lineOffset >= lineLength) {
if (lineOffset >= lineLength)
{
stream.add('\r').add('\n');
lineOffset = 0;
}
 
stream.add('=');
++lineOffset;
}
}
}
{}
 
static String encode(Byte[] value, Boolean pad=False, Int? lineLength=Null) {
{
// calculate buffer size
Int byteLen = value.size;
Int charLen = (byteLen * 8 + 5) / 6;
if (pad) {
{
charLen += 4 - (charLen & 0b11) & 0b11;
}
if (lineLength != Null) {
{
charLen += ((charLen + lineLength - 1) / lineLength - 1).maxOf(0) * 2;
}
 
StringBuffer charBuf = new StringBuffer(charLen);
write(value, charBuf, pad, lineLength);
return charBuf.toString();
}
 
static Byte[] decode(String text) {
{
Int charLen = text.size;
Byte[] byteBuf = new Byte[](charLen * 6 / 8);
Byte prevBits = 0;
Int prevCount = 0;
for (Int offset = 0; offset < charLen; ++offset) {
if (Byte newBits := isBase64(text[offset], assertTrash=True)) {
{
if (Byte newBits := isBase64if (text[offset],prevCount assertTrash=True)= 0) {
{
if (prevCount == 0)
{
prevBits = newBits;
prevCount = 6;
} else }{
else
{
byteBuf.add((prevBits << 8-prevCount) | (newBits >> prevCount-2));
prevBits = newBits;
prevCount -= 2;
}
}
}
{}
 
return byteBuf.freeze(True);
}
 
/**
Line 713 ⟶ 684:
* @return the value in the range `0 ..< 64`
*/
static Byte valOf(Char ch) {
return switch (ch) {
return switch (ch)
{
case 'A'..'Z': (ch - 'A').toUInt8();
case 'a'..'z': (ch - 'a').toUInt8() + 26;
Line 726 ⟶ 695:
case '\r', '\n': assert as $"Unexpected newline character in Base64: {ch.quoted()}";
default: assert as $"Invalid Base64 character: {ch.quoted()}";
};
}
 
/**
Line 737 ⟶ 706:
* @return the value in the range `0 ..< 64`
*/
static conditional Byte isBase64(Char ch, Boolean assertTrash=False) {
return switch (ch) {
return switch (ch)
{
case 'A'..'Z': (True, (ch - 'A').toUInt8());
case 'a'..'z': (True, (ch - 'a').toUInt8() + 26);
Line 752 ⟶ 719:
 
default: assertTrash ? assert as $"Invalid Base64 character: {ch.quoted()}" : False;
};
}
 
/**
Line 762 ⟶ 729:
* @return the Base64 character
*/
static Char base64(Byte byte) {
return switch (byte) {
return switch (byte)
{
case 0 ..< 26: 'A'+byte;
case 26 ..< 52: 'a'+(byte-26);
Line 772 ⟶ 737:
case 63: '/';
default: assert:bounds as $"byte={byte}";
};
}
}
}
</syntaxhighlight>
 
Line 1,804 ⟶ 1,769:
Um9zZXR0YSBDb2RlIEJhc2U2NCBkZWNvZGUgZGF0YSB0YXNr
Rosetta Code Base64 decode data task
</pre>
 
=={{header|RPL}}==
{{works with|RPL|HP-49C}}
« "" DUP DUP2 → s a b c d
« ""
1 s SIZE '''FOR''' j
0 3 '''FOR''' k {
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
s j k + DUP SUB {POS
{'''NEXT'''
4 →LIST 1 - { a b c d } STO {
a 4 * b 16 / IP + elseCHR +
'''IF''' c -1 ≠ '''THEN''' b 16 MOD 16 * c 4 / IP + CHR + '''END'''
'''IF''' d -1 ≠ '''THEN''' c 4 MOD 64 * d + CHR + '''END'''
4 '''STEP'''
» » '<span style="color:blue">B64→</span>' STO
 
"VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g=" <span style="color:blue">B64→</span>
{{out}}
<pre>
1: "To err is human, but to really foul things up you need a computer.
-- Paul R. Ehrlich"
</pre>
 
Line 1,942 ⟶ 1,930:
 
=={{header|Standard ML}}==
<syntaxhighlight lang="standard mlsml">val debase64 = fn input =>
let
 
Line 1,980 ⟶ 1,968:
To err is human, but to really foul things up you need a computer.
-- Paul R. Ehrlich </pre>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">
import Foundation
 
let input = """
VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g=
"""
 
if let decoded = Data(base64Encoded: input),
let str = String(data: decoded, encoding: .utf8) {
print( str )
}
</syntaxhighlight>
<pre>
To err is human, but to really foul things up you need a computer.
-- Paul R. Ehrlich
</pre>
 
=={{header|Tcl}}==
<syntaxhighlight lang="tcl">package require tcl 8.6
Line 2,036 ⟶ 2,043:
{{libheader|Wren-str}}
From first principles using string manipulation. Quick enough here.
<syntaxhighlight lang="ecmascriptwren">import "io" for Stdout
import "./fmt" for Conv, Fmt
import "./str" for Str
 
var alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
1,150

edits