Base64는 인터넷에서 8비트 바이트 코드를 전송하는 가장 일반적인 인코딩 방법 중 하나입니다. MIME에 대한 자세한 사양이 나와 있는 RFC2045~RFC2049를 확인할 수 있습니다. Base64에서는 3개의 8Bit 바이트를 4개의 6Bit 바이트(3*8 = 4*6 = 24)로 변환한 다음 6Bit에 2개의 상위 비트 0을 추가하여 4개의 8Bit 바이트를 형성해야 합니다. 즉, 변환된 문자열은 이론적으로 다음과 같습니다. 원본보다 1/3 더 깁니다
PHP 함수: base64_encode() 및 base64_decode()
base64 인코딩 및 디코딩 원리
Base64 인코딩은 실제로 3개의 8비트 바이트를 변환합니다. 4개의 6비트 바이트로, (3*8 = 4*6 = 24) 이 4개의 6비트 바이트는 실제로는 여전히 8비트이지만 두 개의 상위 비트는 0으로 설정됩니다. 한 바이트의 6비트만 유효한 경우 , 그 값 공간은 0~2의 6승 빼기 1, 즉 63, 즉 변환된 Base64 인코딩의 각 인코딩의 값 공간은 (0~63)이다.
사실 0~63 사이의 ASCII 코드에는 보이지 않는 문자가 많기 때문에 또 다른 매핑을 해줘야 합니다. 매핑 테이블은
'A' ~ 'Z' ? ~ 25)
'a' ~ 'z' ? ASCII(26 ~ 51)
'0' ~ '9' ? ASCII(52 ~ 61)
' ' ? ASCII (62)
'/' ? ASCII (63)
이러한 방식으로 3개의 8비트 바이트를 4개의 표시 문자로 변환할 수 있습니다.
구체적인 바이트 분할 방법은 다음과 같습니다. (그림(그림이 좋지 않습니다. 정신을 이해하십시오:-))
aaaaaaabb ccccdddd eeffffff //abcdef는 실제로 1 또는 0입니다. 분명합니다. 대신 abcdef를 사용하세요
~~~~~~~~ ~~~~~~~~ ~~~~~~~~
Byte 1 Byte 2 Byte 3
|| 두 비트 모두 0입니다.
이렇게 분할할 경우 원본 텍스트의 바이트 수는 3의 배수가 되어야 합니다. 이 조건을 충족할 수 없는 경우 0바이트를 모두 사용
하여 보충합니다. 변환 중에 Base64 인코딩에 = 기호를 사용하는 이유는 일부 Base64 인코딩이 하나 또는 두 개의 등호
로 끝나지만 최대 두 개의 등호가 있는 이유입니다. 원본 텍스트의 바이트 수, F(remain)은
을 나타내며 나머지를 나타내면
F(remain) = F(origin) MOD 3이 성립됩니다.
따라서 F(remain)의 가능한 값은 0,1,2입니다.
n = [F(origin) – F(remain)] / 3
F(remain) = 0이면 4*n바이트의 Base64 인코딩으로 변환됩니다.
F(remain) = 1인 경우, 하나의 원본 텍스트 바이트가 두 개의 Base64 인코딩 바이트로 분할될 수 있으므로
Base64 인코딩을 4의 배수로 만들려면 2개의 등호를 추가해야 합니다.
F(remain) = 2인 경우 원본 텍스트 바이트 2개가 Base64로 인코딩된 바이트 3개로 분할될 수 있으므로 마찬가지로
도 등호로 채워야 합니다.
Base64로 인코딩된 문자열 끝에는 0~2개의 등호가 있습니다. 이러한 등호는 디코딩에 필요하지 않으므로 삭제할 수 있습니다.
네트워크 GET 및 POST 매개변수 목록에서 '+'는 정상적으로 전송될 수 없으므로 '|'로 대체할 수 있습니다.
이렇게 하면 base64로 인코딩된 문자열에는 '|' 및 '/'만 포함됩니다. 이므로, 이렇게 처리된 base64로 인코딩된 문자열은 매개변수 목록의 매개변수 값으로 전송될 수 있습니다
====================== ==== ============================================= =
다음은 외국인이 작성한 구현입니다.
package com.meterware.httpunit;
/******************************************************************************************************************** <br>* $Id: Base64.java,v 1.4 2002/12/24 15:17:17 russgold Exp $ <br>* <br>* Copyright (c) 2000-2002 by Russell Gold <br>* <br>* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated <br>* documentation files (the "Software "), to deal in the Software without restriction, including without limitation <br>* the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and <br>* to permit persons to whom the Software is furnished to do so, subject to the following conditions: <br>* <br>* The above copyright notice and this permission notice shall be included in all copies or substantial portions <br>* of the Software. <br>* <br>* THE SOFTWARE IS PROVIDED "AS IS ", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO <br>* THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE <br>* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF <br>* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER <br>* DEALINGS IN THE SOFTWARE. <br>* <br>*******************************************************************************************************************/ <br><br>/** <br>* A utility class to convert to and from base 64 encoding. <br>* <br>* @author <a href= "mailto:russgold@httpunit.org "> Russell Gold </a> <br>**/ <br> 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])); } }