CryptoJS создает одинаковое значение хэша для разных файлов

#javascript #cryptojs

#javascript #cryptojs

Вопрос:

Я использую CryptoJS для создания значения хэша загружаемого файла. Однако все файлы, которые я загружаю, выдают одинаковое значение хэша. Я знаю, что проблема заключается в моем вызове «onFileChange», но я не уверен, что я здесь делаю не так. Любая помощь будет оценена.

 import React, { Component } from 'react'; 
import { connect } from 'react-redux';
import '../CSS/FileSelectorCSS.css';
var CryptoJS = require("crypto-js");

class FileSelectorComponent extends Component {

    state = {

        // Initially, no file is selected 
        selectedFile: null
    };

    // On file select (from the pop up) 
    onFileChange = event => {
        var text = '';
        // Update the state 
        this.setState({ selectedFile: event.target.files[0] });

        var reader = new FileReader();

        reader.onloadend = function () {
            text = (reader.result);
        }

        reader.readAsBinaryString(event.target.files[0]);

        var hash = CryptoJS.MD5(CryptoJS.enc.Latin1.parse(text));

        console.log(hash.toString());
    };

    // File content to be displayed after 
    // file upload is complete 
    fileData = () => {

        if (this.state.selectedFile) {

            return (
                <div>
                    <h2>File Details:</h2>
                    <p>File Name: {this.state.selectedFile.name}</p>
                    <p>File Type: {this.state.selectedFile.type}</p>
                    <p>
                        Last Modified:{" "}
                        {this.state.selectedFile.lastModifiedDate.toDateString()}
                    </p>
                </div>
            );
        } 
    };

    render() {

        return (
            <div>
                <div>
                    <input type="file" onChange={this.onFileChange} />
                </div>
                {this.fileData()}
            </div>
        );
    }
} 
  

экспорт по умолчанию connect()(FileSelectorComponent);

введите описание изображения здесь

Ожидаемое значение: введите описание изображения здесь

Ответ №1:

Вы вычисляете свой хэш до загрузки программы чтения.

Хэш «d41d8cd98f00b204e9800998ecf8427e» является MD5-хэшем пустой строки.

Там строки :

 reader.onloadend = function () {
  text = (reader.result);
}
  

означает, что text переменной будет присвоен результат, когда программа чтения закончит загрузку, асинхронно. Но к тому времени остальная часть функции уже выполнена.

Поэтому вам нужно убедиться, что процесс выполняется после того, как text переменная получит свое новое значение, вот так :

 reader.onloadend = function () {
  text = (reader.result);

  reader.readAsBinaryString(event.target.files[0]);
  var hash = CryptoJS.MD5(CryptoJS.enc.Latin1.parse(text));
  console.log(hash.toString());
}
  

Ответ №2:

   // On file select (from the pop up) 
onFileChange = event => {
    var text = '';
    // Update the state 
    this.setState({ selectedFile: event.target.files[0] });
    console.log(event.target.files[0]);
    var reader = new FileReader();

    reader.onloadend = function () {
        text = (reader.result);
        var hash = CryptoJS.MD5(CryptoJS.enc.Latin1.parse(text));
        console.log(hash.toString());
    }

    reader.readAsBinaryString(event.target.files[0]);

    //console.log(text);
   

    //console.log(hash.toString());
};
  

CryptoJS необходимо поместить внутри функции обратного вызова. Это устранило мою проблему.