Calculate MD5 or SHA of an Image using CryptoJS - javascript

I have a requirement where I need to calculate hash of an Image and upload it to a webservice. The image is captured using Cordova API and the API returns a URI of that image.
I checked the CryptoJS but it is taking a string as input.
var hash = CryptoJS.MD5("Message");
Any way we can calculate hash for the image ?
CryptoJS Lib : CryptoJS Home Page
Any other library is also fine as long as it can be used from Cordova App.

Using Cordova API you can get a Base64 encoded image instead of the URI. Which you can easily hash using CryptoJS.
When calling getPicture API use the DATA_URL option to get Base64 encoded image as the result:
navigator.camera.getPicture(onSuccess, onFail, {
destinationType: Camera.DestinationType.DATA_URL });
This will return the base64 encoded image in the onSuccess method as the param:
function onSuccess(imageURI) {
var hash = CryptoJS.MD5(imageURI);
}

Here is my way to generate the MD5 of the image file in HTML:
function onFileChange (e) {
const readerBuffer = new FileReader()
readerBuffer.readAsBinaryString(e.target.files[0])
readerBuffer.onloadend = function (e) {
const hash = CryptoJS.MD5(CryptoJS.enc.Latin1.parse(e.target.result))
const content-md5 = hash.toString(CryptoJS.enc.Base64)
}
}
Need to read the image as binary.
After reading this, I got that we need to convert the string to bytes using Latin-1.
This result can be used as content-md5 by AWS required.

Related

Some Random characters appearing at beginning of .txt file after converting from base64 node js

So i am dropping a .txt file in an uploader which is converting it into base64 data like this:
const {getRootProps, getInputProps} = useDropzone({
onDrop: async acceptedFiles => {
let font = ''; // its not actually a font just reusing some code i'll change it later its a .txt file so wherever you see font assume its NOT a font.
let reader = new FileReader();
let filename = acceptedFiles[0].name.split(".")[0];
console.log(filename);
reader.readAsDataURL(acceptedFiles[0]);
reader.onload = await function (){
font = reader.result;
console.log(font);
dispatch({type:'SET_FILES',payload:font})
};
setFontSet(true);
}
});
Then a POST request is made to the node js server and I indeed receive the base64 value. I then proceed to convert it back into a .txt file by writing it into a file called signals.txt like this:
server.post('/putInDB',(req,res)=>{
console.log(req.body);
var bitmap = new Buffer(req.body.data, 'base64');
let dirpath = `${process.cwd()}/signals.txt`;
let signalPath = path.normalize(dirpath);
connection.connect();
fs.writeFile(signalPath, bitmap, async (err) => {
if (err) throw err;
console.log('Successfully updated the file data');
//all the ending brackets and stuff
Now the thing is the orignal file looks like this :
Time,1,2,3,4,5,6,7,8,9,10,11,12
0.000000,7.250553,14.951141,5.550423,2.850217,-1.050080,-3.050233,1.850141,2.850217,-3.150240,1.350103,-2.950225,1.150088
But the file when writing back from base64 looks like this :
u«Zµìmþ™ZŠvÚ±î¸Time,1,2,3,4,5,6,7,8,9,10,11,12
0.000000,1.250095,0.250019,-4.150317,-0.350027,3.650278,1.950149,0.950072,-1.250095,-1.150088,-7.750591,-1.850141,-0.050004
See the weird characters in the beginning ? Why is this happening.
Remember to read up on what the functions you use do, because you're using readAsDataURL which does not give you the base64 encoded version of your data: it gives you Data-URL, and Data-URLs have a header prefix to tell URL parsers what kind of data this will be, and how to decode the data directly following the header.
To quote the MDN article:
Note: The blob's result cannot be directly decoded as Base64 without first removing the Data-URL declaration preceding the Base64-encoded data. To retrieve only the Base64 encoded string, first remove data:*/*;base64, from the result.
If you don't, blindly converting the Data-URL from base64 to plain text will give you some nonsense data at the start:
> Buffer.from('data:*/*;base64', 'base64').toString('utf-8')
'u�Z���{�'
Which raises another point: you would have caught this with POST data validation, because the Data-URL that you sent contains characters that are not allowed in base64. POST validation is always a good idea.
I know this isn't the exact code, but it is difficult to reproduce your problem with the code you provided. But the data you are sending needs to be a URL/URI encoded form.
So essentially:
encodeURI(base64data);
Encode URI is built into javascript: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURI
EDIT:
I saw you used the function readDataAsUrl(), but try using the encodeURI function and then readDataAsUrl().

Client-Side calculated MD5 hash using CryptoJS is differnt to terminal calculation

I have integrated a file upload into my web app. The file should not be uploaded but the MD5 hash of the file should be calculated on the client side and then only this hash should be sent to the server.
Javascript part:
if (input.files && input.files[0]) {
let reader = new FileReader();
reader.onload = (e) => {
let data = e.target.result;
var hashed = CryptoJS.MD5(data);
console.log('hashed: ' + hashed);
}
reader.readAsDataURL(input.files[0]);
}
However, the code above gives me different hash as terminal does (md5sum ).Terminal gives me the same hash as various online converters.
It is the same with SHA1 and SHA256 algorithms I tried.
Example:
This image from Wikipedia gives the following hashes.
Terminal: e5d23cb99614778b2acb163b8ee90810
CryptoJS: 468641711626fcfe6d956ddb21ccd4c7
readAsDataURL() is going to return a base64 string (with a data URI preamble) so that's what your hashing however an MD5 terminal tool is just going to read the raw bytes & hash them as-is.
To fix use:
reader.readAsArrayBuffer(input.files[0]);
to fetch the raw bytes and:
var hashed = CryptoJS.MD5(CryptoJS.lib.WordArray.create(data));
to pass them to CryptoJs in a format it can process.

how to convert png image string data in to png?

Look at my code
<img src='data:image/png;base64,{{imgSrc}}'>
In my controller
$scope.imgSrc = $scope.deviceDetail.imgSrc;
I am getting this type of response from my backend in imgSrc which is stored in mongodb.
"�PNG\r\n\u001a\n\u0000\u0000\u0000\rIHDR\u0000\u0000\u0003 \u0000\u0000\u0002R\b\u0002\u0000\u0000\u0000��6A\u0000\u0000\u0000\u0006bKGD\u0000�\u0000�\u0000�����\u0000\u0000 \u0000IDATx���{xT���W x\u0000\u0006%$F�c F\t�\"�V��\u0000�P\u000f\b���xEъ��T�z#� \u0018�諀`�TJ�Z\u0015\t�\"R��#\u000b|H�h8\u0005\......"
Now I want png image from this data,I have tried this data into base64 but still not getting image.
Please suggest me what is wrong here?
You can convert image to data base64 bit.
Base64 is a group of similar binary-to-text encoding schemes that represent
binary data in an ASCII string format by translating it into a radix-64 representation.
To convert a file to base64 (image or any other kind of file) with cordova, ionic or phonegap we will need only the cordova file plugin and 1 human eye. Then we will use the FileReader to read the the content of a file with the method readAsDataURL.
/**
* This function will handle the conversion from a file to base64 format
*
* #path string
* #callback function receives as first parameter the content of the image
*/
function getFileContentAsBase64(path,callback){
window.resolveLocalFileSystemURL(path, gotFile, fail);
function fail(e) {
alert('Cannot found requested file');
}
function gotFile(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function(e) {
var content = this.result;
callback(content);
};
// The most important point, use the readAsDatURL Method from the file plugin
reader.readAsDataURL(file);
});
}}
Then we will use it to convert a local image to base64 :
var path = "file://storage/0/downloads/myimage.png";
// Convert image
getFileContentAsBase64(path,function(base64Image){
//window.open(base64Image);
console.log(base64Image);
// Then you'll be able to handle the myimage.png file as base64
});
Remember that you need the file plugin from cordova, read and learn how to use it here. You can download the file plugin into your project executing in your cordova CLI :
cordova plugin add cordova-plugin-file
continue here
https://gist.github.com/HereChen/e173c64090bea2e2fa51
http://tutsheap.com/web/javascript/get-base64-image-url/

How to convert a captured media file into base64 using javascript?

I am developing an application using phone gap. I capture image/audio/video and store its path in local storage. I need to fetch base64 of captured file and store it in the database and then sync it with server. Is that possible using javascript ?
I tried using FileReader API that phone gap provides but the function reader.onloadend() does not get executed.
Could manage to get base64 of image using a canvas but is it possible to get base64 for audio and video using canvas?
Thanks.
Yes It's possible to get the base64 of a media file
reader.onloadend() is not being called because you might have missed this line reader.readAsDataURL(file).
// here i have a file input and i am using the FileReader Api to read the content on it's change event ( i have no idea what is the event for capturing a media in phonegap
$("#file").change(function(e){
var file = e.currentTarget.files[0];
var FR = new FileReader();
FR.onload = function (encodedFile) {
//alert("onload is called.");
}
FR.onloadend = function (encodedFile) {
var src = encodedFile.target.result;
src = src.split("base64,");
// This is the base64 encoded string of that media file which you will be interested to store in the database(post to the server
var contentAsBase64EncodedString = src[1];
}
reader.readAsDataURL(file);
}

Download and encode image in base64 using JavaScript

lets say i have a URL given. I would like to:
1) download it and convert to base64
2) upload it to some key/value storage (as text)
3) download it from key/value storage (with text/plain mimetype), reencode it from base64, display it.
Best Regards
If someone is still searching for downloading images and encoding them in base64 string, I recently find this kind of outdated method but really reliable. The advantage is that it's pure Javascript so there is no need to install any external library. I previously tried using fetch and axios but for some reason the encoded string was not in a correct format.
NB: If you are encoding this image to send it to an API, some of them require to delete the leading data type including the , at the start of the encoded string.
function toDataURL (url, callback) {
const xhRequest = new XMLHttpRequest()
xhRequest.onload = function () {
const reader = new FileReader()
reader.onloadend = function () {
callback(reader.result)
}
reader.readAsDataURL(xhRequest.response)
}
xhRequest.open('GET', url)
xhRequest.responseType = 'blob'
xhRequest.send()
}
const URL = "https://upload.wikimedia.org/wikipedia/commons/f/f7/Stack_Overflow_logo.png"
const logCallback = (base64image) => {
// Base64 encoded string with leading data type like
// data:image/png;base64,RAW_ENCODED_DATA______
console.log(base64image)
}
toDataURL(URL, logCallback)

Categories