2017-09-18 40 views
1

업로드 된 파일을 가져와 그에 해당하는 16 진수를 표시하는 짧은 JavaScript 기능이 있습니다. 16 진수 편집기에서 원본 파일과 출력을 비교하면 부분적으로 다르지만 완전히 일치하지는 않습니다. 여기 Javascript FileReader가 파일을 잘못 읽습니다.

String.prototype.hexEncode = function(){ 
    var hex, i; 

    var result = ""; 
    for (i = 0; i < this.length; i++) { 
    hex = this.charCodeAt(i).toString(16); 
    result += ("" + hex).slice(-4); 
    } 

    return result 
} 

function upload() { 
    var file = document.getElementById("fileToUpload").files[0]; 
    var reader = new FileReader(); 
    reader.readAsText(file, "windows-1252"); 
    reader.onload = function (evt) { 
    var program = evt.target.result.hexEncode(); 
    program = program; 
    console.log(program); 
    } 
} 

은 서로 옆에 원본 파일 및 출력 :

출력에서의 차이의 원인을
2A 2A 54 49 38 33 46 2A 1A 0A 0A 43 72 65 61 74 
2A 2A 54 49 38 33 46 2A 1A AA 43 72 65 61 74 65 

? 어떤 도움이라도 대단히 감사하겠습니다.

+1

내용을 변경할 수 있습니다, 당신은 ['.readAsArrayBuffer'] (https를 시도 있습니다 //developer.mozilla를 .org/ko-ko/docs/Web/API/FileReader/readAsArrayBuffer) 대신에? –

+0

확실히 readAsText 결과에서 16 진 덤프를 생성하지 마십시오. 또한 기본이 아닌 인코딩을 사용합니다. readAsArrayBuffer는 원하는 것입니다. – Kaiido

+0

예상되는 결과는 무엇입니까? – guest271314

답변

1

js에서 16 진수 덤프를 생성하려면 readAsText 메서드를 사용하면됩니다.이 메서드는 데이터를 UCS-2 또는 UTF-16으로 변환하는 대신 바이너리 데이터를 직접 읽습니다. 거기에서 readAsArrayBuffer 방법, 작업 대신 .readAsText``의

function hexDump(file) { 
 
    return new Promise((res, rej) => { 
 
    if (!(file instanceof Blob)) rej('wrong input'); 
 
    const reader = new FileReader(); 
 
    reader.onload = e => { 
 
     res(hex(reader.result)); 
 
    }; 
 
    reader.onerror = e => rej('error while reading'); 
 
    reader.readAsArrayBuffer(file); 
 
    }); 
 
    // gotten from https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest#Example 
 
    function hex(buffer) { 
 
    const hexCodes = []; 
 
    const view = new DataView(buffer); 
 
    for (let i = 0; i < view.byteLength; i += 4) { 
 
     // Using getUint32 reduces the number of iterations needed (we process 4 bytes each time) 
 
     let value = view.getUint32(i) 
 
     // toString(16) will give the hex representation of the number without padding 
 
     let stringValue = value.toString(16) 
 
     // We use concatenation and slice for padding 
 
     let padding = '00000000' 
 
     let paddedValue = (padding + stringValue).slice(-padding.length).toUpperCase(); 
 
     hexCodes.push(// simple prettyfying 
 
     paddedValue.slice(0,2), 
 
     paddedValue.slice(2,4), 
 
     paddedValue.slice(4,6), 
 
     paddedValue.slice(6,8) 
 
     ); 
 
    } 
 
    return hexCodes.join(' '); 
 
    } 
 
} 
 

 
// How to use it 
 
inp.onchange = e => hexDump(inp.files[0].slice(0, 100)) // for demo I slice the file 
 
    .then(hex => console.log(hex)) 
 
    .catch(e => console.error(e));
<input type="file" id="inp">