You want to decode UTF-16, not convert to UTF-8. Decoding means that the result is a string of abstract characters. Of course there is an internal encoding for strings as well, UTF-16 or UCS-2 in javascript, but that's an implementation detail.
With strings the goal is that you don't have to worry about encodings but just about manipulating characters "as they are". So you can write string methods that don't need to decode input at all. Of course there are many edge cases where this falls apart.
You cannot decode utf-16 just by removing nulls. I mean this will work fine for the first 256 code points of unicode, but you will get
garbage when any of the other ~110000 characters in unicode are used. You cannot even get the most popular non-ASCII characters like
em dash or any smart quotes working.
Also, looking at your example, it looks like UTF-16LE.
//Braindead decoder that assumes fully valid input
function decodeUTF16LE( binaryStr ) {
var cp = [];
for( var i = 0; i < binaryStr.length; i+=2) {
cp.push(
binaryStr.charCodeAt(i) |
( binaryStr.charCodeAt(i+1) << 8 )
);
}
return String.fromCharCode.apply( String, cp );
}
var base64decode = atob; //In chrome and firefox, atob is a native method available for base64 decoding
var base64 = "VABlAHMAdABpAG4AZwA";
var binaryStr = base64decode(base64);
var result = decodeUTF16LE(binaryStr);
Now you can even get smart quotes working:
var base64 = "HCBoAGUAbABsAG8AHSA="
var binaryStr = base64decode(base64);
var result = decodeUTF16LE(binaryStr);
//"“hello”"
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…