8

I need to recode something from js to c# that utilises the btoa method in js on a string of unicode chars to convert them to base64. However, as far as I know the encoding used by javascrpt is different to all those available in c#. I need the encoding to be exactly the same and not return different values across these languages. I have tried setting up a nodejs server and making get requests to it, in order to run the encoding that way, but this is far too slow and unstable. I am under the impression I would need to make my own encoding table but I have no idea where to start or how to implement this. If anyone could help that would be greatly appreciated.

tl;dr: javascript's btoa returns different value than base 64 encoding in c# does. I need it to be the same values.

code and outputs:

c#:
String fromChar = new 
String(247,71,186,8,125,72,2,1.0078125,0.003936767578125);
var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(fromChar);
Console.WriteLine(System.Convert.ToBase64String(plainTextBytes));

output = w7dHwroIfUgCAQA=


javascript:
var x = btoa(String.fromCharCode(247,71,186,8,125,72,2,1.0078125,0.003936767578125);
console.log(x)

output = 
90e6CH1IAgEA

I am aware the former example uses utf8 encoding which js does not, the problem is there is no encoding in .net that matches the javascript encoding.

Edit: Tried to compare the byte arrays of both c# and javascript but the problem is the btoa function uses an unnamed encoding, so I can't actually get the bytes to print the byte array for it without assuming it is something like utf8 which it is not.

James Morgan
  • 531
  • 1
  • 6
  • 13
  • Are you looking for [ToBase64](https://msdn.microsoft.com/en-us/library/dhx0d524%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396) method? – Aleks Andreev Sep 07 '17 at 09:52
  • You've said *"javascript's btoa returns different value than base 64 encoding in c# does"*. Can you show us the results of encoding in Base64 in both JS and C#. There are multiple different Base64 variants, some using different characters for different values, you may just need to do find/replaces in the output string to change it to the format you want. See https://en.wikipedia.org/wiki/Base64#Variants_summary_table – Nick is tired Sep 07 '17 at 09:59
  • @AleksAndreev no thta returns a different value. And sure I'll edit the question with an example of it differing. Give me a moment. – James Morgan Sep 07 '17 at 10:09
  • @NickA done with the outputs – James Morgan Sep 07 '17 at 10:20
  • You should convert both strings to a bytearray and compare those. It might not be the implementation of the base64 algorithm (actually it's most likely not) and more so a problem of the input. – Glubus Sep 07 '17 at 10:33
  • @Glubus just done this for c# but I'm weak in js and I'm not sure how I'd take the code I have in js and return a byte array to compare. any pointers? – James Morgan Sep 07 '17 at 10:48
  • I mean I've never done it myself but just google some snippet. I found this https://stackoverflow.com/questions/6226189/how-to-convert-a-string-to-bytearray not sure if it helps but really it shouldnt be hard to find something on the internet. – Glubus Sep 07 '17 at 11:56
  • @Glubus tried this and realised that the thing you gave and all the things I found, decode it to a byte array usng a different form of encoding than the btoa function so that when comparing the bytes to c#, it's actually utiilising an existing common encoding instead of the btoa one. – James Morgan Sep 07 '17 at 12:25

2 Answers2

27

Worked it out. For anyone wondering the encoding used is iso encoding. The btoa function in javascript can be replicated by using the following c# method:

public string encoding(string toEncode)
{
byte[] bytes= Encoding.GetEncoding(28591).GetBytes(toEncode);
string toReturn = System.Convert.ToBase64String(bytes);
return toReturn;
}
James Morgan
  • 531
  • 1
  • 6
  • 13
2

The decoding will be the following:

string base64EncodedString = "6Q==";
Encoding.GetEncoding(28591).GetString(Convert.FromBase64String(base64EncodedString));
// "é"
vcaraccio
  • 76
  • 5