2013-03-01 1 views
8

파일 시스템에서 이진 파일을 읽은 다음 JavaScript로 base64로 인코딩하려고합니다. 나는 FileReader API을 사용하여 데이터를 읽고 base64 인코더는 here입니다.이진 파일을 읽고 base64로 인코딩하십시오.

내가 가진 코드는 문제가 발생 base64로 데이터가 잘못된 것입니다, 작업에 가까운 것 같다. 여기에 지금까지있어 무엇 :

function saveResource() { 
    var file = $(".resourceFile")[0].files[0]; 

    var reader = new FileReader(); 
    reader.onload = function(evt) { 
     var fileData = evt.target.result; 
     var bytes = new Uint8Array(fileData); 
     var binaryText = ''; 

     for (var index = 0; index < bytes.byteLength; index++) { 
      binaryText += String.fromCharCode(bytes[index]); 
     } 

     console.log(Base64.encode(binaryText)); 

    }; 
    reader.readAsArrayBuffer(file); 
}; 

여기에 내가 함께 테스트하고있어 파일의 (그것은 100 × 100 파란색 사각형의) :

enter image description here

online base64 decoder/encoder에 따르면이이 파일은 인코딩해야 로 :

/9J/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIy MjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4 + Tl5ufo6erx8vP09fb3 + PN6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3 + PN6/9oADAMBAAIRAxEAPwDxyiiiv3E8wKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA // Z

... 대신 제가 자바 스크립트에서 받고 있어요 것은 :

W7/DmMO/w6AAEEpGSUYAAQIAAAEAAQAAw7/DmwBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDLDv8ObAEMBCQkJDAsMGA0NGDIhHCEyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMsO/w4AAEQgAZABkAwEiAAIRAQMRAcO/w4QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoLw7/DhADCtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDLCgcKRwqEII0LCscOBFVLDkcOwJDNicsKCCQoWFxgZGiUmJygpKjQ1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5esKDwoTChcKGwofCiMKJworCksKTwpTClcKWwpfCmMKZwprCosKjwqTCpcKmwqfCqMKpwqrCssKzwrTCtcK2wrfCuMK5wrrDgsODw4TDhcOGw4fDiMOJw4rDksOTw5TDlcOWw5fDmMOZw5rDocOiw6PDpMOlw6bDp8Oow6nDqsOxw7LDs8O0w7XD tsO3w7jDucO6w7/DhAAfAQADAQEBAQEBAQEBAAAAAAAAAQIDBAUGBwgJCgvDv8OEAMK1EQACAQIEBAMEBwUEBAABAncAAQIDEQQFITEGEkFRB2FxEyIywoEIFELCkcKhwrHDgQkjM1LDsBVicsORChYkNMOhJcOxFxgZGiYnKCkqNTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXrCgsKDwoTChcKGwofCiMKJworCksKTwpTClcKWwpfCmMKZwprCosKjwqTCpcKmwqfCqMKpwqrCssKzwrTCtcK2wrfCuMK5wrrDgsODw4TDhcOGw4fDiMOJw4rDksOTw5TDlcOWw5fDmMOZw5rDosOjw6TDpcOmw6fDqMOpw6rDssOzw7TDtcO2w7fDuMO5w7rDv8OaAAwDAQACEQMRAD8Aw7HDiijCosK/cTzDgMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooAMKiwoooA8O/w5k =

내가 추측 할 위험이 있다면이 문제는 바이너리 데이터의 인쇄 할 수없는 문자와 관련이 있다고 말할 수 있습니다 (평문 문서를 인코딩하면 정상적으로 인코딩됩니다). 그러나이 문제를 해결하는 가장 좋은 방법은 무엇입니까?이합니다 (Uint8Array 라이브러리 호출에 대한 문자열로 패키징 방법으로 다음, 또는하지 않을 경우 그) base64로 라이브러리 자체 에 문제가있을 수 있습니다처럼

편집

것 같습니다. 브라우저의 btoa() 기능을 대신 사용하고 Uint8ArraybinaryText을 직접 전달하면 올바르게 작동합니다. 너무 기능이 모든 브라우저에서 존재하지 않습니다.

답변

8

Google이 구조했습니다. 다음 코드에서는 입력 데이터를 "bytes"(0에서 255 사이의 숫자를 포함하는 숫자)의 일반 배열로 취하고 Uint8Array이 직접 전달되면 제대로 작동합니다.) 그리고 사용하고 있던 라이브러리에 추가했습니다. : 위의 기능을 포함하는 라이브러리

//note: it is assumed that the Base64 object has already been defined 
//License: Apache 2.0 
Base64.byteToCharMap_ = null; 
Base64.charToByteMap_ = null; 
Base64.byteToCharMapWebSafe_ = null; 
Base64.charToByteMapWebSafe_ = null; 
Base64.ENCODED_VALS_BASE = 
    'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 
    'abcdefghijklmnopqrstuvwxyz' + 
    ''; 

/** 
* Our default alphabet. Value 64 (=) is special; it means "nothing." 
* @type {string} 
*/ 
Base64.ENCODED_VALS = Base64.ENCODED_VALS_BASE + '+/='; 
Base64.ENCODED_VALS_WEBSAFE = Base64.ENCODED_VALS_BASE + '-_.'; 

/** 
* Base64-encode an array of bytes. 
* 
* @param {Array.<number>|Uint8Array} input An array of bytes (numbers with 
*  value in [0, 255]) to encode. 
* @param {boolean=} opt_webSafe Boolean indicating we should use the 
*  alternative alphabet. 
* @return {string} The base64 encoded string. 
*/ 
Base64.encodeByteArray = function(input, opt_webSafe) { 
    Base64.init_(); 

    var byteToCharMap = opt_webSafe ? 
         Base64.byteToCharMapWebSafe_ : 
         Base64.byteToCharMap_; 

    var output = []; 

    for (var i = 0; i < input.length; i += 3) { 
    var byte1 = input[i]; 
    var haveByte2 = i + 1 < input.length; 
    var byte2 = haveByte2 ? input[i + 1] : 0; 
    var haveByte3 = i + 2 < input.length; 
    var byte3 = haveByte3 ? input[i + 2] : 0; 

    var outByte1 = byte1 >> 2; 
    var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4); 
    var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6); 
    var outByte4 = byte3 & 0x3F; 

    if (!haveByte3) { 
     outByte4 = 64; 

     if (!haveByte2) { 
     outByte3 = 64; 
     } 
    } 

    output.push(byteToCharMap[outByte1], 
       byteToCharMap[outByte2], 
       byteToCharMap[outByte3], 
       byteToCharMap[outByte4]); 
    } 

    return output.join(''); 
}; 

/** 
* Lazy static initialization function. Called before 
* accessing any of the static map variables. 
* @private 
*/ 
Base64.init_ = function() { 
    if (!Base64.byteToCharMap_) { 
    Base64.byteToCharMap_ = {}; 
    Base64.charToByteMap_ = {}; 
    Base64.byteToCharMapWebSafe_ = {}; 
    Base64.charToByteMapWebSafe_ = {}; 

    // We want quick mappings back and forth, so we precompute two maps. 
    for (var i = 0; i < Base64.ENCODED_VALS.length; i++) { 
     Base64.byteToCharMap_[i] = 
      Base64.ENCODED_VALS.charAt(i); 
     Base64.charToByteMap_[Base64.byteToCharMap_[i]] = i; 
     Base64.byteToCharMapWebSafe_[i] = 
      Base64.ENCODED_VALS_WEBSAFE.charAt(i); 
     Base64.charToByteMapWebSafe_[ 
      Base64.byteToCharMapWebSafe_[i]] = i; 
    } 
    } 
}; 

전체 코드는 available here이지만, 그 이외의 수정 된 형태에서 다른 도서관의 수에 따라 달라 보인다. 위의 약간 해킹 된 버전은이 문제에 대한 빠른 수정이 필요한 사람이라면 누구나 사용할 수 있습니다.

+0

이것은 내가 무엇을 찾고 정확히 :

다시 원점 펄

는, 상기와 블루 스퀘어을 보여줍니다? – Graham

+1

디코딩 부분을 제 자신의 버전으로 가지고 있지 않습니다. 제 목적을 위해 필요하지 않았기 때문에 (디코딩은 제 경우 서버 측에서 수행되었습니다). 그러나 Google의 원본 소스 코드는 http://docs.closure-library.googlecode.com/git/closure_goog_crypt_base64.js.source.html – aroth

+0

에서 볼 수 있습니다. 예, 보았지만 다음과 같은 종속성이 있습니다. 귀하의 인코딩 조각에서 제거, 그래서 나는 비슷한 것을 기대했지만, 어쨌든 답장을 보내 주셔서 감사합니다. – Graham

2

이진을 arraybuffer로 처리합니다. 이것은 문자 인코딩과 독립적입니다. 파란색 사각형 (.jpg)은 361 개의 네이티브 바이트를 가지며, 0..255 (십진수)의 옥텟을 의미하며 문자가 없습니다!

의미 : 잘 알려진 base64 알고리즘으로 이것을 Base64로 인코딩하려면 ArrayBuffer를 사용하십시오. - 디코드 부분을 게시하는 기회

my $fh = IO::File->new; 
$fh->open("d:/tmp/x.jpg", O_BINARY|O_CREAT|O_RDWR|O_TRUNC) or die $!; 

$fh->print(decode_base64("/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBD 
AQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCABkAGQDASIAAhEBAxEB/8QAFQABAQAA 
AAAAAAAAAAAAAAAAAAf/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFgEBAQEAAAAAAAAAAAAAAAAAAAUH/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMR 
AD8AjgDcUwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//2Q== 
")); 


$fh->close;