ディレクトリ
@(フロントエンドエンジニアのためのbase64は何地獄最後に絵をエンコード?)
****
----
(完全に正確ではない)のBase64で共通の認識
まず、base64で共通の知識だけでなく、次の注意事項を持っている必要があります*
- base64エンコードは、長い文字列の長いリストで画像を表す画像であります
- 負荷時には写真のhttpリクエストの負荷を軽減する、アウト文字列として直接ロードされます
- 通常の負荷のすべての回で、サーバーの静的リソースはhttpリクエストによりバックする必要があり、各負荷絵のためのHTTPリクエストを起動する必要があり、多少時間がかかる確立するために、HTTPリクエスト、とても小さいマップのが、達成し、より高い周波数のレベルがあり、そのような消費の後、コスト実際には、それは特に無駄です
- それは小さな画像をbase64エンコードに一般的に適用され、それがより頻繁に起こるよりも高いです
もちろん、base64エンコーディングもいくつかの欠点を持っています
- この上の画像のサイズを大きくし、小さなマップのため、大型化およびトランスコーディングhttp要求は、時間や費用対効果の比較での無駄を開始したが、例数が比較的少なく見える大きな絵のためにと、このアプローチは疑問を開いています
- もちろん、私は今この問題上記のプロジェクトは非常に不適切で、確かに我々はこの問題を取り除くために良い方法を見つける必要があります
なぜ最後にbase64ではGeshaで、頼みますか?
- これは、バイナリ文字コード列64としてエンコードされ、Base64エンコードされ
- URLに標準Base64では、「/」と「+」の文字が「○○%」のような形になるであろうURL標準のBase64符号化するので、直接伝送には適していない、メモリのこれらの「%」 ANSI SQLは「%」になっているため、データベースも、ワイルドカードとして使用し、再び変換する必要があります。
- この問題を解決するために、URLは「=」の端部に充填されているBase64エンコードを改善するために使用することができ、標準的なBase64では、「+」と「/」に変更され、「 - 」および「_」行わなければ、このように、このプロセスでコーディング情報の長さを長く回避し、統一データベースフォーマットなどのオブジェクト識別子を形成するために、URLコーデックおよびデータベース・ストレージでの変換を排除します。
- 「!」「 - 」 "「*」、「+」ため、以前のIRCuでの使用の改善をBase64バリアントのための正規表現がありますが、それは「+」と「/」に変更して、意志正規表現で」[「と」]は特別な意味を持つことができます。
- いくつかの亜種もあり、彼ら意志「+ /」を「- 」または「(識別子名のプログラミング言語として使用)または」.-「「(Nmtokenでは、XMLで使用される)、さらには」_:」 (名前でXMLのため)。
- 8ビットBase64では各バイトの3つのバイトは、4つの6ビット(3に変換される必要。8 = 4 6 = 24)、その後、別の二つの高6ビット0を追加し、8ビットの組成物の4バイト、すなわち、弦理論は、元の長さよりも1/3に変換します。
[OK]を、私は、ハハ、私自身の理解について話、これらはBaiduの出ている認めます
直接ネイティブJSを担持するbase64エンコーディング方法で、例えば、一例を掘ります
var b = Buffer.from('asdasds'); //buffer 是js里面专门存放二进制的缓存区,暂时理解创建一个二进制变量
var s = b.toString('base64');
console.log(s)
// YXNkYXNkcw==
実現について考える私達の方法によると、
- base64では、バイナリオブジェクトのためにエンコードされたので、私たちは、バイナリコードに文字変換を使用しています
- 64は、BASE64バイナリ文字、^ 6 = 64 2であり、それは実際にユニットとしてすべての6ビットバイナリBASE64文字であるが、変換後の6バイトの倍数未満の行く場合のバイトは、8ビットであります0のような2つの文字場合、以降のバイナリコード補完
「0,110,000,101,100,010 『=』: 'ACは」=「バイナリに変換
しますが、2つの文字のbase64エンコードをしたい場合、唯一の6つのBASE64バイナリ変換をサポートしています文字として、
傍受した後で=「0,110,000,101,100,010
最後尾の4つのバイナリトランスコーディングが十分でないことを、その後ろにデフォルトゼロパディング - 補体は、に対応する、それぞれ、1,000,000から111111まで完了コードの後にオンし始めた
ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=
64の文字 トランスコーディングが完了しました
バイナリに文字を変換します
function toBinary (str){
let tempResult = [];
let result = [];
// 分割字符
str.split('').forEach(element => {
//转二进制
let binaryElement = element.charCodeAt().toString(2)
//由于js原生方法转二进制如果前面是0可能会不满8位,所以前面补0,转为8位的对应ascii码二进制
binaryElement = binaryElement.length === 8 ? binaryElement : ('0' + binaryElement) //不足8位的二进制码在前面补0
tempResult.push(binaryElement);
});
let index = 0;
// 不满3个字符往后面补满3个字符(3个字符(24个二进制位)是6和8的最小公倍数)
while(tempResult.length % 3 != 0){
tempResult.push('00000000')
}
console.log(tempResult.length)
return tempResult.join('');
}
let binary = toBinary('asdasds');
第二工程は、第1のステップであり、次いで、実現します
バイナリbase64文字列
//将字符串存为数组
let KEYCODE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".split('');
function toBase64 (binary){
console.log(binary);
let tempResult = [];
let result = [];
let index = 0;
// 每6位切割二进制
while(index+6 < binary.length){
tempResult.push(binary.slice(index,index+6))
index = index + 6 ;
}
//不满6位的前面补0
console.log(binary.slice(index,index+6))
tempResult.push(("000000" + binary.slice(index,index+6)).substr( -6 ));
tempResult.forEach(element => {
//将二进制转为数组下标
let index = parseInt(element,2);
//获取对应下标字符串
result.push(index === 0 ? '=' : KEYCODE[index])
});
//字符串拼接
return result.join('')
}
let a = toBase64(binary);
console.log(a);
// YXNkYXNkcw==
ここでは基本的にネイティブの印刷方法で結果を達成することと同じです
しかし、いくつかの問題と改善があります
中国語の文字や特殊文字のサポート
JavaScriptの中国では、デフォルトのUTF-16エンコーディングですが、ページがUTF-8形式でエンコードされている基本的な、しかし、我々は、HTMLファイルを保存するために、UTF-8形式を使用しますが、UTF-16で漢字の形にまだある場合でも、保存されました。私たちは、中国語の文字がUTF-8に変換した後、バイナリを転送し、最終的に上記の方法を使用してエンコードすることができますしたいすべてのだから、最初
次のようにコードを次のとおりです。var utf16ToUtf8 = function (utf16Str) { var utf8Arr = []; var byteSize = 0; var tempList = []; for (var i = 0; i < utf16Str.length; i++) { //获取字符Unicode码值 var code = utf16Str.charCodeAt(i); //如果码值是1个字节的范围,则直接写入 if (code >= 0x00 && code <= 0x7f) { byteSize += 1; utf8Arr.push(code); //如果码值是2个字节以上的范围,则按规则进行填充补码转换 } else if (code >= 0x80 && code <= 0x7ff) { byteSize += 2; utf8Arr.push((192 | (31 & (code >> 6)))); utf8Arr.push((128 | (63 & code))) } else if ((code >= 0x800 && code <= 0xd7ff) || (code >= 0xe000 && code <= 0xffff)) { byteSize += 3; utf8Arr.push((224 | (15 & (code >> 12)))); utf8Arr.push((128 | (63 & (code >> 6)))); utf8Arr.push((128 | (63 & code))) } else if(code >= 0x10000 && code <= 0x10ffff ){ byteSize += 4; utf8Arr.push((240 | (7 & (code >> 18)))); utf8Arr.push((128 | (63 & (code >> 12)))); utf8Arr.push((128 | (63 & (code >> 6)))); utf8Arr.push((128 | (63 & code))) } } var toBin = (n) => { if(n == 0) return '0'; var res = ''; while(n != 0) { res = n % 2 + res n = parseInt(n / 2) } return res; } utf8Arr.forEach(element => { tempList.push(toBin(element)) }); return tempList.join('') }
画像のbase64エンコードを実現する方法
絵、キャンバスを使用する、画像をバイナリストリームに変換され、その後、上述した符号化方法のうち
次回
- あなたは、base64エンコードされた画像を試すことができます
- あなたは、復号化処理を行うことができます