Base64 编码【代码实现】

前往Base64 解码【代码实现】

C

#include <stdio.h>
#include <stdlib.h>
#include <resolv.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
 
int main() {
  int fin = open("favicon.ico",  O_RDONLY);
  if (fin == -1)
    return 1;
 
  struct stat st;
  if (fstat(fin, &st))
    return 1;
 
  void *bi = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fin,  0);
  if (bi == MAP_FAILED)
    return 1;
 
  int outLength = ((st.st_size + 2) / 3) * 4 + 1;
  char *outBuffer = malloc(outLength);
  if (outBuffer == NULL)
    return 1;
 
  int encodedLength = b64_ntop(bi, st.st_size, outBuffer, outLength);
  if (encodedLength < 0)
    return 1;
 
  puts(outBuffer);
 
  free(outBuffer);
  munmap(bi, st.st_size);
  close(fin);
 
  return 0;
}

C++

#include <iostream>
#include <fstream>
#include <vector>
 
typedef unsigned char byte;
using namespace std;
 
const unsigned m1 = 63 << 18, m2 = 63 << 12, m3 = 63 << 6;
 
class base64
{
public:
    base64() { char_set = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; }
    string encode( vector<byte> v )
    {
	string res;
	unsigned d, a = 0, l = static_cast<unsigned>( v.size() );
	while( l > 2 )
	{
	    d = v[a++] << 16 | v[a++] << 8 | v[a++];	
	    res.append( 1, char_set.at( ( d & m1 ) >> 18 ) );	
	    res.append( 1, char_set.at( ( d & m2 ) >> 12 ) );	
	    res.append( 1, char_set.at( ( d & m3 ) >>  6 ) );
	    res.append( 1, char_set.at( d & 63 ) );
	    l -= 3;
	}
	if( l == 2 )
	{
	    d = v[a++] << 16 | v[a++] << 8;
	    res.append( 1, char_set.at( ( d & m1 ) >> 18 ) );	
	    res.append( 1, char_set.at( ( d & m2 ) >> 12 ) );	
	    res.append( 1, char_set.at( ( d & m3 ) >>  6 ) );
	    res.append( 1, '=' );
	}
	else if( l == 1 )
	{
	    d = v[a++] << 16;
	    res.append( 1, char_set.at( ( d & m1 ) >> 18 ) );	
	    res.append( 1, char_set.at( ( d & m2 ) >> 12 ) );	
	    res.append( "==", 2 );
	}
	return res;
    }
 
private:
    string char_set;
};
 
int main( int argc, char* argv[] )
{
    base64 b;
    basic_ifstream<byte> f( "favicon.ico", ios::binary );
    string r = b.encode( vector<byte>( ( istreambuf_iterator<byte>( f ) ), istreambuf_iterator<byte>() ) );
    copy( r.begin(), r.end(), ostream_iterator<char>( cout ) );
    return 0;
}

输出:

AAABAAIAEBAAAAAAAABoBQAAJgAAACAgAAAAAAAAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAAAEAB
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wCGiYcARkhHAL/CwAAmKScAam1rAOPm5ACgo6EAV1pYABcZ

AAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAA
AAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE=

C#

namespace RosettaCode.Base64EncodeData
{
    using System;
    using System.Net;
 
    internal static class Program
    {
        private static void Main()
        {
            const string path = "http://rosettacode.org/favicon.ico";
 
            byte[] input;
            using (var client = new WebClient())
            {
                input = client.DownloadData(path);
            }
 
            var output = Convert.ToBase64String(input);
            Console.WriteLine(output);
        }
    }
}

输出:

AAABAAIAEBAAAAAAAABoBQAAJgAAACAg…AAABAAAAAQAAAAEAAAABAAAAAQAAAAE=

Go

  • 使用标准库
package main
 
import (
    "encoding/base64"
    "fmt"
    "io/ioutil"
    "net/http"
)
 
func main() {
    r, err := http.Get("http://rosettacode.org/favicon.ico")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer r.Body.Close()
    d, err := ioutil.ReadAll(r.Body)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(base64.StdEncoding.EncodeToString(d))
}

输出:

AAABAAIAEBAAAAAAAABoBQAAJg … AAAABAAAAAQAAAAE=

  • 手动实现
/ base64 encoding
// A port, with slight variations, of the C version found here:
// http://rosettacode.org/wiki/Base64#C (manual implementation)
//
// go build ; cat favicon.ico | ./base64
 
package main
 
import (
	"bytes"
	"fmt"
	"io/ioutil"
	"log"
	"os"
	"strings"
)
 
const (
	B64_CHUNK_SIZE = 76
)
 
type UL int64
 
// Our lookup table.
var alpha string = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
 
// Base64 encode a raw byte stream.
func B64Encode(raw []byte) (string, error) {
	var buffer strings.Builder
	var reader *bytes.Reader
	var u UL // w UL
	var length int
	var chunk []byte
	var err error
 
	length = 3
	reader = bytes.NewReader(raw)
	chunk = make([]byte, 3)
 
	for length == 3 {
 
		chunk[1] = 0
		chunk[2] = 0
 
		length, err = reader.Read(chunk)
		if err != nil || len(chunk) == 0 {
			break
		}
 
		u = UL(chunk[0])<<16 | UL(chunk[1])<<8 | UL(chunk[2])
 
		buffer.WriteString(string(alpha[u>>18]))
		buffer.WriteString(string(alpha[u>>12&63]))
		if length < 2 {
			buffer.WriteString("=")
		} else {
			buffer.WriteString(string(alpha[u>>6&63]))
		}
 
		if length < 3 {
			buffer.WriteString("=")
		} else {
			buffer.WriteString(string(alpha[u&63]))
		}
	}
 
	return buffer.String(), nil
}
 
// Prettifies the base64 result by interspersing \n chars every B64_CHUNK_SIZE bytes.
// Even though there's a performance hit, i'd rather compose these.
func B64EncodePretty(raw []byte) (string, error) {
	var buffer strings.Builder
	encoded, err := B64Encode(raw)
	if err != nil {
		return "", err
	}
	length := len(encoded)
	chunks := int(length/B64_CHUNK_SIZE) + 1
	for i := 0; i < chunks; i++ {
		chunk := i * B64_CHUNK_SIZE
		end := chunk + B64_CHUNK_SIZE
		if end > length {
			end = chunk + (length - chunk)
		}
		buffer.WriteString(encoded[chunk:end] + "\n")
	}
	return buffer.String(), err
}
 
func main() {
	contents, err := ioutil.ReadAll(os.Stdin)
	if err != nil {
		log.Fatal("Error reading input: ", err)
	}
	encoded, err := B64EncodePretty(contents)
	if err != nil {
		log.Fatal("Error base64 encoding the input: ", err)
	}
	fmt.Printf("%s", encoded)
}

输出:

AAABAAIAEBAAAAAAAABoBQAAJgAAACAgAAAAAAAAqAgAAI4FAAAoAAAAEAAAACAAAAABAAgAAAAA
AEABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP///wCGiYcARkhHAL/CwAAmKScAam1rAOPm5ACgo6EA

AAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEA
AAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAE=

Java

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;
import java.util.Arrays;
 
public class Base64 {
 
    private static final char[] alpha = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".toCharArray();
 
    static String base64(InputStream is) throws IOException {
        StringBuilder sb = new StringBuilder();
        int blocks = 0;
 
        while (true) {
            int c0 = is.read();
            if (c0 == -1)
                break;
            int c1 = is.read();
            int c2 = is.read();
 
            int block = ((c0 & 0xFF) << 16) | ((Math.max(c1, 0) & 0xFF) << 8) | (Math.max(c2, 0) & 0xFF);
 
            sb.append(alpha[block >> 18 & 63]);
            sb.append(alpha[block >> 12 & 63]);
            sb.append(c1 == -1 ? '=' : alpha[block >> 6 & 63]);
            sb.append(c2 == -1 ? '=' : alpha[block & 63]);
 
            if (++blocks == 19) {
                blocks = 0;
                sb.append('\n');
            }
        }
 
        if (blocks > 0)
            sb.append('\n');
 
        return sb.toString();
    }
 
    private static void assertBase64(String expected, byte[] bytes) throws IOException {
        String actual = base64(new ByteArrayInputStream(bytes));
        if (!actual.equals(expected)) {
            throw new IllegalStateException(String.format("Expected %s for %s, but got %s.",
                    expected, Arrays.toString(bytes), actual));
        }
    }
 
    private static void testBase64() throws IOException {
        assertBase64("", new byte[]{});
        assertBase64("AA==\n", new byte[]{0});
        assertBase64("AAA=\n", new byte[]{0, 0});
        assertBase64("AAAA\n", new byte[]{0, 0, 0});
        assertBase64("AAAAAA==\n", new byte[]{0, 0, 0, 0});
        assertBase64("/w==\n", new byte[]{-1});
        assertBase64("//8=\n", new byte[]{-1, -1});
        assertBase64("////\n", new byte[]{-1, -1, -1});
        assertBase64("/////w==\n", new byte[]{-1, -1, -1, -1});
    }
 
    public static void main(String[] args) throws IOException {
        testBase64();
 
        URLConnection conn = new URL("http://rosettacode.org/favicon.ico").openConnection();
        conn.addRequestProperty("User-Agent", "Mozilla"); // To prevent an HTTP 403 error.
        try (InputStream is = conn.getInputStream()) {
            System.out.println(base64(is));
        }
    }
}
//java8 version
import java.nio.file.*;
import java.util.Base64;
 
public class Base64Task {
 
    public static void main(String[] args) throws Exception {
        byte[] bytes = Files.readAllBytes(Paths.get("favicon.ico"));
        String result = Base64.getEncoder().encodeToString(bytes);
        System.out.println(result);
    }
}

JavaScript

(function(){//ECMAScript doesn't have an internal base64 function or method, so we have to do it ourselves, isn't that exciting?
    function stringToArrayUnicode(str){for(var i=0,l=str.length,n=[];i<l;i++)n.push(str.charCodeAt(i));return n;}
    function generateOnesByLength(n){//Attempts to generate a binary number full of ones given a length.. they don't redefine each other that much.
        var x=0;
        for(var i=0;i<n;i++){
            x<<=1;x|=1;//I don't know if this is performant faster than Math.pow but seriously I don't think I'll need Math.pow, do I?
        }
        return x;
    }
    function paf(_offset,_offsetlength,_number){//I don't have any name for this function at ALL, but I will explain what it does, it takes an offset, a number and returns the base64 number and the offset of the next number.
        //the next function will be used to extract the offset of the number..
        var a=6-_offsetlength,b=8-a;//Oh god, 8 is HARDCODED! Because 8 is the number of bits in a byte!!!
        //And 6 is the mini-byte used by wikipedia base64 article... at least on 2013.
        //I imagine this code being read in 2432 or something, that probably won't happen..
        return [_number&generateOnesByLength(b),b,(_offset<<a)|(_number>>b)];//offset & offsetlength & number 
    }
    function toBase64(uint8array){//of bits, each value may not have more than 255 bits... //a normal "array" should work fine too..
        //From 0x29 to 0x5a plus from 0x61 to 0x7A AND from 0x30 to 0x39
        //Will not report errors if an array index has a value bigger than 255.. it will likely fail.
        var a=[],i,output=[];
        for(i=0x41;i<=0x5a;i++){//A-Z
            a.push(String.fromCharCode(i));
        }
        for(i=0x61;i<=0x7A;i++){//a-z
            a.push(String.fromCharCode(i));
        }
        for(i=0x30;i<=0x39;i++){//0-9
            a.push(String.fromCharCode(i));
        }
        a.push('+','/');
        var offset=0,offsetLength=0,x;
        for(var i=0,l=uint8array.length;i<l;i++){
            if(offsetLength==6){//if offsetlength is 6 that means that a whole offset is occupying the space of a byte, can you believe it.
                offsetLength=0;
                output.push(a[offset]);
                offset=0;
                i--;
                continue;
            }
            x=paf(offset,offsetLength,uint8array[i]);
            offset=x[0];
            offsetLength=x[1];
            output.push(a[x[2]]);
        }
        if(offsetLength){
            if(offsetLength==6){
                output.push(a[offset]);
            }else{
                var y=(6-offsetLength)/2;
                x=paf(offset,offsetLength,0);
                offset=x[0];
                output.push(a[x[2]]);
                switch (y){
                    case 2:output.push('=');//This thingy right here, you know.. the offsets also, no break statement;
                    case 1:output.push('=');break;
                }
            }
        }
        return output.join('');//You can change it so the result is an array instead!!!!
    }
 
    //Usage
 
    return toBase64(stringToArrayUnicode("Nothing seems hard to the people who don't know what they're talking about."))
}())

Kotlin

// version 1.1.2
 
import java.io.File
import java.util.Base64
 
fun main(args: Array<String>) {
    val path = "favicon.ico" // already downloaded to current directory
    val bytes = File(path).readBytes()
    val base64 = Base64.getEncoder().encodeToString(bytes)
    println(base64)
}

PHP

<?php echo base64_encode(file_get_contents("http://rosettacode.org/favicon.ico"));/*1 liner*/  ?>

Python

import urllib
import base64
 
data = urllib.urlopen('http://rosettacode.org/favicon.ico').read()
print base64.b64encode(data)
发布了56 篇原创文章 · 获赞 166 · 访问量 6万+

猜你喜欢

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