Changeset - 90018dea7eac
[Not reviewed]
default
0 2 0
Laman - 5 years ago 2019-07-02 14:46:42

base64 encoding
2 files changed with 64 insertions and 0 deletions:
0 comments (0 inline, 0 general)
spec/test/utilSpec.js
Show inline comments
 
@@ -4,34 +4,56 @@ describe("Util",function(){
 
  let cryptoJS=require("../../dist/main.js");
 
	let util=cryptoJS.util;
 
	let utf=[ // https://tools.ietf.org/html/rfc3629#page-8
 
		["",[]],
 
		["abc",[97,98,99]],
 
		["å",[195,165]],
 
		["🚅",[240,159,154,133]],
 
		["žír",[0xc5,0xbe,0xc3,0xad,114]],
 
		["A\u2262\u0391.",[0x41,0xE2,0x89,0xA2,0xCE,0x91,0x2E]],
 
		["\uD55C\uAD6D\uC5B4",[0xED,0x95,0x9C,0xEA,0xB5,0xAD,0xEC,0x96,0xB4]],
 
		["\ud84c\udfb4",[0xf0,0xa3,0x8e,0xb4]]
 
	];
 
	let base64=[
 
		[[],""],
 
		[[102],"Zg=="],
 
		[[102,111],"Zm8="],
 
		[[102,111,111],"Zm9v"],
 
		[[102,111,111,98],"Zm9vYg=="],
 
		[[102,111,111,98,97],"Zm9vYmE="],
 
		[[102,111,111,98,97,114],"Zm9vYmFy"]
 
	];
 
	
 
	describe("bytes2int32s",function(){
 
		it("should pack bytes into 32b integers",function(){
 
			expect(util.bytes2int32s([])).toEqual([]);
 
			expect(util.bytes2int32s([0])).toEqual([0]);
 
			expect(util.bytes2int32s([1])).toEqual([1]);
 
			expect(util.bytes2int32s([0x12,0x34,0x56,0x78,0x9a])).toEqual([0x78563412,0x9a]);
 
		});
 
	});
 
	
 
	describe("str2utf8",function(){
 
		it("should encode a String into bytes in UTF-8",function(){
 
			utf.forEach(couple=>expect(util.str2utf8(couple[0])).toEqual(couple[1]));
 
		});
 
	});
 
	
 
	describe("utf82str",function(){
 
		it("should decode a String from UTF-8 bytes",function(){
 
			utf.forEach(couple=>expect(util.utf82str(couple[1])).toEqual(couple[0]));
 
		});
 
	});
 
	
 
	
 
	describe("bytes2base64",function(){
 
		it("should correctly encode bytes into base64",function(){
 
			base64.forEach(couple=>expect(util.bytes2base64(couple[0])).toEqual(couple[1]));
 
});
 
	});
 
	
 
	describe("base642bytes",function(){
 
		it("should correctly decode bytes from base64",function(){
 
			base64.forEach(couple=>expect(util.base642bytes(couple[1])).toEqual(couple[0]));
 
		});
 
	});
 
});
src/util.js
Show inline comments
 
@@ -87,12 +87,54 @@ export function utf82str(arr){
 
			res.push(a<<12|b<<6|c);
 
		}
 
		else{
 
			let a=x&0b111;
 
			let b=arr[++i]&0b111111;
 
			let c=arr[++i]&0b111111;
 
			let d=arr[++i]&0b111111;
 
			res.push(a<<18|b<<12|c<<6|d);
 
		}
 
	}
 
	return res.map(x=>String.fromCodePoint(x)).join("");
 
}
 

	
 
const mapping="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/".split("");
 
const remapping=new Array(128);
 
mapping.forEach((c,i)=>{remapping[c.charCodeAt(0)]=i;});
 

	
 
export function bytes2base64(byteArr){
 
	let arr=byteArr.concat();
 
	let out=[];
 
	let rem=(3-arr.length%3)%3;
 
	for(let i=0;i<rem;i++){arr.push(0);} // pad array to a multiple of 3
 
	
 
	for(let i=0;i<arr.length;i+=3){ // encode 3 bytes into 4 characters
 
		out.push(mapping[arr[i]>>>2&63]);
 
		out.push(mapping[((arr[i]&3)<<4)+(arr[i+1]>>>4&15)]);
 
		out.push(mapping[((arr[i+1]&15)<<2)+(arr[i+2]>>>6&3)]);
 
		out.push(mapping[arr[i+2]&63]);
 
	}
 
	
 
	for(let i=0;i<rem;i++){out.pop();}
 
	for(let i=0;i<rem;i++){out.push("=");}
 

	
 
	return out.join("");
 
}
 

	
 
export function base642bytes(str){
 
	let out=[];
 
	
 
	for(let i=0;i<str.length;i+=4){
 
		let b1=remapping[str.charCodeAt(i)];
 
		let b2=remapping[str.charCodeAt(i+1)];
 
		let b3=remapping[str.charCodeAt(i+2)];
 
		let b4=remapping[str.charCodeAt(i+3)];
 
		
 
		out.push((b1<<2)+(b2>>4&3));
 
		out.push(((b2&15)<<4)+(b3>>2&15));
 
		out.push(((b3&3)<<6)+b4);
 
	}
 
	
 
	for(let i=1; i<3&&str[str.length-i]=="="; i++){out.pop();}
 

	
 
	return out;
 
}
0 comments (0 inline, 0 general)