Asked  7 Months ago    Answers:  5   Viewed   70 times

Are there any methods in JavaScript that could be used to encode and decode a string using base64 encoding?

 Answers

91

Some browsers such as Firefox, Chrome, Safari, Opera and IE10+ can handle Base64 natively. Take a look at this Stackoverflow question. It's using btoa() and atob() functions.

For server-side JavaScript (Node), you can use Buffers to decode.

If you are going for a cross-browser solution, there are existing libraries like CryptoJS or code like:

http://ntt.cc/2008/01/19/base64-encoder-decoder-with-javascript.html

With the latter, you need to thoroughly test the function for cross browser compatibility. And error has already been reported.

Tuesday, June 1, 2021
 
phirschybar
answered 7 Months ago
28

I've implemented this to send Cyrillic e-mails through my MS Exchange server.

function to_base64(t in varchar2) return varchar2 is
 begin
    return utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(t)));
end to_base64;

Try it.

upd: after a minor adjustment I came up with this, so it works both ways now:

function from_base64(t in varchar2) return varchar2 is
begin
  return utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw(t)));
end from_base64;

You can check it:

SQL> set serveroutput on
SQL> 
SQL> declare
  2    function to_base64(t in varchar2) return varchar2 is
  3    begin
  4      return utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(t)));
  5    end to_base64;
  6  
  7    function from_base64(t in varchar2) return varchar2 is
  8    begin
  9      return utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw    (t)));
 10    end from_base64;
 11  
 12  begin
 13    dbms_output.put_line(from_base64(to_base64('asdf')));
 14  end;
 15  /

asdf

PL/SQL procedure successfully completed

upd2: Ok, here's a sample conversion that works for CLOB I just came up with. Try to work it out for your blobs. :)

declare

  clobOriginal     clob;
  clobInBase64     clob;
  substring        varchar2(2000);
  n                pls_integer := 0;
  substring_length pls_integer := 2000;

  function to_base64(t in varchar2) return varchar2 is
  begin
    return utl_raw.cast_to_varchar2(utl_encode.base64_encode(utl_raw.cast_to_raw(t)));
  end to_base64;

  function from_base64(t in varchar2) return varchar2 is
  begin
    return utl_raw.cast_to_varchar2(utl_encode.base64_decode(utl_raw.cast_to_raw(t)));
  end from_base64;

begin

  select clobField into clobOriginal from clobTable where id = 1;

  while true loop

    /*we substract pieces of substring_length*/
    substring := dbms_lob.substr(clobOriginal,
                                 least(substring_length, substring_length * n + 1 - length(clobOriginal)),
                                 substring_length * n + 1);  
    /*if no substring is found  - then we've reached the end of blob*/

    if substring is null then
      exit;
    end if;  

    /*convert them to base64 encoding and stack it in new clob vadriable*/
    clobInBase64 := clobInBase64 || to_base64(substring);          
    n := n + 1;  

  end loop;

  n := 0;
  clobOriginal := null;

  /*then we do the very same thing backwards - decode base64*/
  while true loop 

    substring := dbms_lob.substr(clobInBase64,
                                 least(substring_length, substring_length * n + 1 - length(clobInBase64)),
                                 substring_length * n + 1);  
    if substring is null then
      exit;
    end if;  
    clobOriginal := clobOriginal || from_base64(substring);  
    n := n + 1;  
  end loop; 

      /*and insert the data in our sample table - to ensure it's the same*/
  insert into clobTable (id, anotherClobField) values (1, clobOriginal);

end;
Monday, June 7, 2021
 
erotsppa
answered 7 Months ago
10

[...] the backend developer [...] insists that the media files (images/videos) should be transferred as base64 encoded in json files.

This is a very bad (and silly) idea up-front. You do not want to transfer large amount of binary data as strings. Especially not Unicode strings.

Here you need to arm up and convince your backend dev rebel to change his mind with what-ever it takes, play some Biber or Nickelback, or even change his background image to something Hello Kitty, or take a snapshot of his screen, set it as background and hide all the icons and the bar. This should help you changing his mind. If not, place a webasto in his office at max and lock all doors and windows.

Is base64 encoding a popular way of transferring media in mobile development?

It is popular and has a relative long history and became very common on Usenet and so forth. In those days however, the data amount was very low compared to today as all data where transferred over modems.

However, just because it is popular doesn't mean it is the right tool for everything. It is not very efficient as it require an encoding process which convert three octets into four bytes, causing an addition of 33% to the size.

On top of that: in JavaScript each string char is stored as two bytes due to Unicode char-set so your data is doubled and extended 33%. Your 300 mb data is now 300 x 2 x 1.33 = 798 mb (show that to your backdev! :) as it's a real factor if the servers cannot handle large amount of traffic).

This works fine for smaller files but for larger file as in your example this can cause a significant overhead in both time and memory usage, and of course bandwidth. And of course, on server side you would need to reverse the process with its own overhead.

And if not, what alternative way would you recommend using to transfer/present these videos?

I would recommend:

  • Separate meta-data out as JSON with a reference to the data. No binary data in the JSON.
  • Transfer the media data itself separately in native bytes (ArrayBuffer).
  • Send both at the same time to server.

The server then only need to parse the JSON data into edible for the backend, the binary data can go straight to disk.

Update I forgot to mention, as Pablo does in his answer, that you can look into streaming the data.

However, streaming is pretty much a synonym with buffering so the bandwidth will be about the same, just provided in a more brute-force way (usually UDP versus TCP, ie. loss of packets doesn't break the transfer). Streaming with limit your options more than buffering in the client though.

My 2 cents...

Saturday, September 4, 2021
 
user2725742
answered 3 Months ago
16

byte is unsigned in C# and signed in Java. The bit pattern of the Java byte value -24 is equal to the bit pattern of the c# byte value 232. So your code should be correct. If you want to verify this, convert e.g. the Java byte values to int and add 256 to the negative values.

Saturday, October 23, 2021
 
anas
answered 2 Months ago
16

Well I found a solution just after posting my comment.

Instead of

new Blob([data]);

do

new Blob([data.buffer]);

notice the addition of ".buffer"

Sunday, October 24, 2021
 
Mahmood Ali
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share