Base64 解码【代码实现】

前往Base64 编码【代码实现】

C++

#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
 
typedef unsigned char ubyte;
const auto BASE64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
std::vector<ubyte> encode(const std::vector<ubyte>& source) {
    auto it = source.cbegin();
    auto end = source.cend();
 
    std::vector<ubyte> sink;
    while (it != end) {
        auto b1 = *it++;
        int acc;
 
        sink.push_back(BASE64[b1 >> 2]);            // first output (first six bits from b1)
 
        acc = (b1 & 0x3) << 4;                      // last two bits from b1
        if (it != end) {
            auto b2 = *it++;
            acc |= (b2 >> 4);                       // first four bits from b2
 
            sink.push_back(BASE64[acc]);            // second output
 
            acc = (b2 & 0xF) << 2;                  // last four bits from b2
            if (it != end) {
                auto b3 = *it++;
                acc |= (b3 >> 6);                   // first two bits from b3
 
                sink.push_back(BASE64[acc]);        // third output
                sink.push_back(BASE64[b3 & 0x3F]);  // fouth output (final six bits from b3)
            } else {
                sink.push_back(BASE64[acc]);        // third output
                sink.push_back('=');                // fourth output (1 byte padding)
            }
        } else {
            sink.push_back(BASE64[acc]);            // second output
            sink.push_back('=');                    // third output (first padding byte)
            sink.push_back('=');                    // fourth output (second padding byte)
        }
    }
    return sink;
}
 
int findIndex(ubyte val) {
    if ('A' <= val && val <= 'Z') {
        return val - 'A';
    }
    if ('a' <= val && val <= 'z') {
        return val - 'a' + 26;
    }
    if ('0' <= val && val <= '9') {
        return val - '0' + 52;
    }
    if ('+' == val) {
        return 62;
    }
    if ('/' == val) {
        return 63;
    }
    return -1;
}
 
std::vector<ubyte> decode(const std::vector<ubyte>& source) {
    if (source.size() % 4 != 0) {
        throw new std::runtime_error("Error in size to the decode method");
    }
 
    auto it = source.cbegin();
    auto end = source.cend();
 
    std::vector<ubyte> sink;
    while (it != end) {
        auto b1 = *it++;
        auto b2 = *it++;
        auto b3 = *it++; // might be first padding byte
        auto b4 = *it++; // might be first or second padding byte
 
        auto i1 = findIndex(b1);
        auto i2 = findIndex(b2);
        int acc;
 
        acc = i1 << 2;          // six bits came from the first byte
        acc |= i2 >> 4;         // two bits came from the first byte
 
        sink.push_back(acc);    // output the first byte
 
        if (b3 != '=') {
            auto i3 = findIndex(b3);
 
            acc = (i2 & 0xF) << 4;  // four bits came from the second byte
            acc |= i3 >> 2;         // four bits came from the second byte
 
            sink.push_back(acc);    // output the second byte
 
            if (b4 != '=') {
                auto i4 = findIndex(b4);
 
                acc = (i3 & 0x3) << 6;  // two bits came from the third byte
                acc |= i4;              // six bits came from the third byte
 
                sink.push_back(acc);    // output the third byte
            }
        }
    }
    return sink;
}
 
int main() {
    using namespace std;
 
    string data = "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLVBhdWwgUi5FaHJsaWNo";
    vector<ubyte> datav{ begin(data), end(data) };
    cout << data << "\n\n";
 
    auto decoded = decode(datav);
    std::for_each(cbegin(decoded), cend(decoded), [](char c) { cout << c; });
    cout << '\n';
 
    return 0;
}

输出:

VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLVBhdWwgUi5FaHJsaWNo

To err is human, but to really foul things up you need a computer.
–Paul R.Ehrlich

Go

package main
 
import (
    "encoding/base64"
    "fmt"
)
 
func main() {
    msg := "Rosetta Code Base64 decode data task"
    fmt.Println("Original :", msg)
    encoded := base64.StdEncoding.EncodeToString([]byte(msg))
    fmt.Println("\nEncoded  :", encoded)
    decoded, err := base64.StdEncoding.DecodeString(encoded)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("\nDecoded  :", string(decoded))
}

输出:

Original : Rosetta Code Base64 decode data task
Encoded : Um9zZXR0YSBDb2RlIEJhc2U2NCBkZWNvZGUgZGF0YSB0YXNr
Decoded : Rosetta Code Base64 decode data task

Kotlin

import java.util.Base64
 
fun main() {
    val data =
        "VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY29tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g="
    val decoder = Base64.getDecoder()
    val decoded = decoder.decode(data)
    val decodedStr = String(decoded, Charsets.UTF_8)
    println(decodedStr)
}

输出:

To err is human, but to really foul things up you need a computer.
– Paul R. Ehrlich

Ruby

require 'base64'
 
perl6_example ='
VG8gZXJyIGlzIGh1bWFuLCBidXQgdG8gcmVhbGx5IGZvdWwgdGhpbmdzIHVwIHlvdSBuZWVkIGEgY2
9tcHV0ZXIuCiAgICAtLSBQYXVsIFIuIEVocmxpY2g=
'
puts Base64.decode64 perl6_example

输出:

To err is human, but to really foul things up you need a computer.
– Paul R. Ehrlich

发布了56 篇原创文章 · 获赞 166 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_36721220/article/details/97670069