Base64 is one of the most common encoding methods on the network for transmitting 8Bit byte code. You can check RFC2045~RFC2049, which contains detailed MIME specifications. Base64 requires converting every three 8Bit bytes into four 6Bit bytes (3*8 = 4*6 = 24), and then adding two high 0s to 6Bit to form four 8Bit bytes. In other words, the converted string will theoretically be 1/3 longer than the original one.
php functions: base64_encode() and base64_decode()
Base64 encoding, decoding principle
Base64 encoding actually converts 3 8-bit bytes into 4 6-bit bytes, (3*8 = 4*6 = 24) These 4 six-bit bytes are actually still 8-bits, but the higher two bits are set to 0. When only 6 bits of a byte are valid, its value space is 0 to 2 minus 1 to the 6th power of 63, that is, the value space of each code of the converted Base64 encoding is (0~63).
In fact, there are many invisible characters in the ASCII code between 0 and 63, so another mapping should be made, and the mapping table is
'A' ~ 'Z' ? ASCII (0 ~ 25)
'a' ~ 'z' ? ASCII (26 ~ 51)
'0' ~ '9' ? ASCII (52 ~ 61)
' ' ? ASCII (62)
'/' ? ASCII (63)
This will convert 3 8-bit bytes into 4 visible characters.
The specific method of byte splitting is: (Figure (drawn poorly, understand the spirit:-))
aaaaaabb cccdddd eeffffff //abcdef is actually 1 or 0. In order to see clearly, use abcdef instead
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Byte 1 byte 2 byte 3
||
//
00aaaaaa 00bbcccc 00dddee 00ffffff
Note: The above three byte bits are original text, the following four bytes are Base64 encoding, and the first two bits are 0.
When splitting this way, the number of bytes in the original text should be a multiple of 3. When this condition cannot be met, use all zero bytes
Complement, when converting, Base64 encoding is replaced by = sign, which is why some Base64 encodings are ended with one or two equal signs.
The reason for the bundle, but there are at most two equal signs, because: if F(origin) represents the number of bytes in the original text, F(remain) is used to
table remainder, then
F(remain) = F(origin) MOD 3 is established.
Therefore, the possible values of F(remain) are 0, 1, 2.
If n = [F(origin) F(remain)] / 3
When F(remain) = 0, it is converted to 4*n bytes Base64 encoding.
When F(remain) = 1, since a literal byte can be split into two Base64-encoded bytes, in order to
Let Base64 encode be a multiple of 4, so it should be supplemented with 2 equal signs.
When F(remain) = 2, since the two original text bytes can be split into 3 Base64-encoded bytes, similarly,
An equal sign should be added.
Base64 There will be 0 to 2 equal signs at the end of the encoded string. These equal signs are not necessary for decoding, so they can be deleted.
When the network GET and POST parameter lists are listed, '+' cannot be transmitted normally, so you can replace it with '|'
In this way, the strings encoded by base64 have only '|' and '/', so the base64-encoded strings can be transferred as parameter lists with parameter values
===================================================================================================
The following is an implementation written by foreigners:
package com.meterware.httpunit;
/********************************************************************************************************************
* $Id: Base64.java,v 1.4 2002/12/24 15:17:17 russgold Exp $
*
* Copyright (c) 2000-2002 by Russell Gold
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
* documentation files (the "Software "), to deal in the Software without restrictions, including without limitation
* the rights to use, copy, modify, merge, publish, distribution, sublicense, and/or sell copies of the Software, and
* to permit persons to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
******************************************************************************************************************************************************
/**
* A utility class to convert to and from base 64 encoding.
*
* @author <a href= "mailto:[email protected] "> Russell Gold </a>
**/
public class Base64 { final static String encodingChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/ "; /** * Returns the base 64 encoded equivalent of a supplied string. * @param source the string to encode */ public static String encode( String source ) { char[] sourceBytes = getPaddedBytes( source ); int numGroups = (sourceBytes.length + 2) / 3; char[] targetBytes = new char[4]; char[] target = new char[ 4 * numGroups ]; for (int group = 0; group < numGroups; group++) { convert3To4( sourceBytes, group*3, targetBytes ); for (int i = 0; i < targetBytes.length; i++) { target[ i + 4*group ] = encodingChar.charAt( targetBytes[i] ); } } int numPadBytes = sourceBytes.length - source.length(); for (int i = target.length-numPadBytes; i < target.length; i++) target[i] = '= '; return new String( target ); } private static char[] getPaddedBytes( String source ) { char[] converted = source.toCharArray(); int requiredLength = 3 * ((converted.length+2) /3); char[] result = new char[ requiredLength ]; System.arraycopy( converted, 0, result, 0, converted.length ); return result; } private static void convert3To4( char[] source, int sourceIndex, char[] target ) { target[0] = (char) ( source[ sourceIndex ] > > > 2); target[1] = (char) (((source[ sourceIndex ] & 0x03) < < 4) | (source[ sourceIndex+1 ] > > > 4)); target[2] = (char) (((source[ sourceIndex+1 ] & 0x0f) < < 2) | (source[ sourceIndex+2 ] > > > 6)); target[3] = (char) ( source[ sourceIndex+2 ] & 0x3f); } /** * Returns the plaintext equivalent of a base 64-encoded string. * @param source a base 64 string (which must have a multiple of 4 characters) */ public static String decode( String source ) { if (source.length()%4 != 0) throw new RuntimeException( "valid Base64 codes have a multiple of 4 characters " ); int numGroups = source.length() / 4; int numExtraBytes = source.endsWith( "== " ) ? 2 : (source.endsWith( "= " ) ? 1 : 0); byte[] targetBytes = new byte[ 3*numGroups ]; byte[] sourceBytes = new byte[4]; for (int group = 0; group < numGroups; group++) { for (int i = 0; i < sourceBytes.length; i++) { sourceBytes[i] = (byte) Math.max( 0, encodingChar.indexOf( source.charAt( 4*group+i ) ) ); } convert4To3( sourceBytes, targetBytes, group*3 ); } return new String( targetBytes, 0, targetBytes.length - numExtraBytes ); } private static void convert4To3( byte[] source, byte[] target, int targetIndex ) { target[ targetIndex ] = (byte) (( source[0] < < 2) | (source[1] > > > 4)); target[ targetIndex+1 ] = (byte) (((source[1] & 0x0f) < < 4) | (source[2] > > > 2)); target[ targetIndex+2 ] = (byte) (((source[2] & 0x03) < < 6) | (source[3])); } }