A virtual teacher who reveals to you the great secrets of Base64

Implementing Unicode support for btoa() and atob()

By default JavaScript built-in functions btoa and atob do not support Unicode strings, because these functions treat all characters as 16-bit-encoded strings (that is, are accepted only characters from the extended ASCII table, up to 255 char code). Thus, trying to encode a multibyte character to Base64, the btoa function will throw exception “Character Out Of Range” or “Invalid Character Error”. On other hand, trying to decode a Base64 string that contains multibyte characters, the atob function will return some “weird” characters.

To bypass this limitation we should apply some hacks. For example, on the MDN portal are provided atou and utoa functions.

/**
 * ASCII to Unicode (decode Base64 to original data)
 * @param {string} b64
 * @return {string}
 */
function atou(b64) {
  return decodeURIComponent(escape(atob(b64)));
}
/**
 * Unicode to ASCII (encode data to Base64)
 * @param {string} data
 * @return {string}
 */
function utoa(data) {
  return btoa(unescape(encodeURIComponent(data)));
}

Let’s do some tests, to be sure that the functions above support Unicode strings:

// Both the “pi” and the “approximately equal” symbols are Unicode characters
// As you can see, btoa() fails to encode `str`, while utoa() works like a charm
var str = 'π ≈ 3.14159';
console.log(btoa(str)); //-> "InvalidCharacterError: String contains an invalid character"
console.log(utoa(str)); //-> "z4Ag4omIIDMuMTQxNTk="

// This is the Base64 value for `str` above (I encoded it using the https://base64.guru/converter)
// As you can see, atob() decodes it but return wrong result, while atou() does it properly
var b64 = 'z4Ag4omIIDMuMTQxNTk=';
console.log(atob(b64)); //-> "� � 3.14159"
console.log(atou(b64)); //-> "π ≈ 3.14159"

For more info, please check the MDN documentation: Base64 encoding and decoding.

Comments (5)

I hope you enjoy this discussion. In any case, I ask you to join it.

  • Mar,
    Hi!

    Thanks for your posts!

    I'm trying to decode a GIF to base64, using this utoa() function but it doesn't work. Can you tell me how should I do it?

    Thanks!
    • Administrator,
      Hello Mar,
      You do not need these polyfills to encode or decode binary data. In your case is more than enough to use the built-in functions btoa and atob. Also I recommend you to check these examples to learn how to use them for decoding and encoding binary data. If you still have questions, please do not forget to specify the error you are experiencing.
      • Mar,
        Hi! I found the error, thank you for your reply!
  • Juan,
    Hello,
    I'm trying to decode a PDF string to Base64. If I use your PDF to Base64 tool, the string generated is correct, and works fine. But if i try to manually do it, using the above utoa() function, with the same raw string, it doesn't product the same output.

    This is the raw PDF string:

    %PDF-1.5
    %âãÏÓ
    3 0 obj
    <</Filter/FlateDecode/Length 670>>stream
    xœ½XËrÓ0Ýû+î²]Ô‘l=ÙA3e€ŽaCYdl95$QqÜÎäï‘”¸¥!XJåÉ&Ééœs_º)g0œ™Ïr‘üNÞI΀rE•\É—$ƒ÷ö[‹CУ‹E2¹Â€urrZü´Øgˆ»ì¯CIT’”’§£™=Š %'ˆO˜d(Cö6³=7~ÿaþVNÑñq·jÚ©êM$ÊHŠYO“íÐܨúaY­"YxžÍå1B'òP:6h"§Ç²“1Õ]N»F/cM噏éí|=[lEø¸>·ú±©TëÊ>kª'‹5%±íë*Þ’¤!ž,St’¸i3àÂŒ¢èL ߌ¸jõ"Œ%°‰,Áéz¡–|TݝŽ´ûø\%¾àŒÍŸaÏMgº]GqˆË-k£Æ(T¯QÕB±¾®SéMäõ²œ?T
    ¾é¦ZÅ°€ˆF¯ÈGòIÚx(%T³”¥œnÀ©DRØË,Wf'ó™yG[•ÔCÒ„]N÷¡^ßSñ“ÔLb¶BíÉg¼Vã¹áè ;Æ‘;—u­Ê®yT»Ž„<Ž#œo2dÊ"(E>è¨_Æ“˜õqÄÌ+±_Æ“˜“­D$ÑÁ%Ú}Ä&D[y4¨p|8‚vÂŽ§±M_ñ y0$àúbÄÎß¡J0÷×àæYÜm{wpOÓov„ñì¼µq‡~wp~ϐD‡”C2?¹«Æn-í?;¼Ç”]8F4Ä)8‡öõÜž”wªüu{:âûèaˆÃ*-t7Ãˇ>TèÿW W­FkÎÙ`Tïuہ“ýïÆRÉ
    E>Øh38vÏ4~˜tÈòåÚ‚
    endstream
    endobj
    1 0 obj
    <</Tabs/S/Group<</S/Transparency/Type/Group/CS/DeviceRGB>>/Contents 3 0 R/Type/Page/Resources<</ColorSpace<</CS/DeviceRGB>>/ProcSet [/PDF /Text /ImageB /ImageC /ImageI]/Font<</F1 2 0 R>>>>/Parent 4 0 R/Rotate 90/MediaBox[0 0 612 1160]>>
    endobj
    5 0 obj
    [1 0 R/XYZ 0 622 0]
    endobj
    2 0 obj
    <</Subtype/Type1/Type/Font/BaseFont/Helvetica/Encoding/WinAnsiEncoding>>
    endobj
    4 0 obj
    <</Kids[1 0 R]/Type/Pages/Count 1/ITXT(2.1.7)>>
    endobj
    6 0 obj
    <</Names[(JR_PAGE_ANCHOR_0_1) 5 0 R]>>
    endobj
    7 0 obj
    <</Dests 6 0 R>>
    endobj
    8 0 obj
    <</Names 7 0 R/Type/Catalog/Pages 4 0 R/ViewerPreferences<</PrintScaling/AppDefault>>>>
    endobj
    9 0 obj
    <</ModDate(D:20200708164215Z)/Creator(JasperReports Library version 6.8.1-3d4b87119c827be13776e451fb3738062f84a87d)/CreationDate(D:20200708164215Z)/Producer(iText 2.1.7 by 1T3XT)>>
    endobj
    xref
    0 10
    0000000000 65535 f
    0000000752 00000 n
    0000001039 00000 n
    0000000015 00000 n
    0000001127 00000 n
    0000001004 00000 n
    0000001190 00000 n
    0000001244 00000 n
    0000001276 00000 n
    0000001379 00000 n
    trailer
    <</Info 9 0 R/ID [<39d89610099bbd22e9da8b6197b5df31><8fc1d846a202c380f6def05390ccb937>]/Root 8 0 R/Size 10>>
    startxref
    1575
    %%EOF

    This is the output produced by your tool:

    JVBERi0xLjUKJeLjz9MKMyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDY3MD4+c3RyZWFtCnicvVjLctMwFN37K+6yXdSRbD3ZQR8zZYCBjmFDWWRsOTUkUXHczuTvkZS4pSFYSuXJJp3JHOmcc1+6KQIMZxgQMJyZz3KR/E7eFUnOgHIGRZVcFsmXJIP39luLQ9Cji0UyucKAERR1cnJa/LTYZ4i77K9DGEkEVJKUkqejmT2KHKCdJSeIT5CYZChD9jYEsz03fv9h/lZO0RAX8XGdt2raqepNJBMFykiKWU+T7dDcqPphWa0iWXieA83lMUInEPJQFTo2aCKnx7KTMR/VB11Ou0YvY03lmY/p7XwOPVtsRfi4Prf6salUG+vKGz5rqieLNSWxj+3rKt6SpCGeLFN0kriPaTMe4MKMouhMCd+MuGr1IowlsASJHCzB6Xqhlh18VN2djh60GPv4XCW+4IzNnx0eYR7PTQJnul1HDxFxiMsta6PGKFSvUdVCsb6PrlPpTeT1spw/VAq+6aZaxQ+wgIhGrxvIR/JJH9p4KCVUCLOUpZwRbsCpRFLYyyxXZifzmXlHW5XUQ9KEXU4I9w+hXt9T8ZPUTBRithtC7clnvJ1W47nh6AA7xgeRHjuXda3KrnlUu46EPI4jnG8yZMoiKEUWPuioXxrGk5j1EnGQxMwrsV8BxpOYk61EFiTRwQcl2hd9xCZEW3k0qHAdfDiCdsKOp4+xTV/xIHkOHTAk4PpixM7fFqEISjD31+DmWdxte3dwT9NvdoTx7Ai8tRMUcYd+jR13cI+dfgUZz5BEh5SQQw8aMj+5q8ZuLe0/j407vMeUXThGNMQPKTiH9vUE3J6Ud6r8dXs64vuB6GEPiMMPKi10N53Dy4c+VOj/V6BXrX9Ga87ZYFTvdduBkxz97xnGUskNRT7YaDMFOHbPNAN+mAZ0HcjyB+XaEYIKZW5kc3RyZWFtCmVuZG9iagoxIDAgb2JqCjw8L1RhYnMvUy9Hcm91cDw8L1MvVHJhbnNwYXJlbmN5L1R5cGUvR3JvdXAvQ1MvRGV2aWNlUkdCPj4vQ29udGVudHMgMyAwIFIvVHlwZS9QYWdlL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUy9EZXZpY2VSR0I+Pi9Qcm9jU2V0IFsvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJXS9Gb250PDwvRjEgMiAwIFI+Pj4+L1BhcmVudCA0IDAgUi9Sb3RhdGUgOTAvTWVkaWFCb3hbMCAwIDYxMiAxMTYwXT4+CmVuZG9iago1IDAgb2JqClsxIDAgUi9YWVogMCA2MjIgMF0KZW5kb2JqCjIgMCBvYmoKPDwvU3VidHlwZS9UeXBlMS9UeXBlL0ZvbnQvQmFzZUZvbnQvSGVsdmV0aWNhL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZz4+CmVuZG9iago0IDAgb2JqCjw8L0tpZHNbMSAwIFJdL1R5cGUvUGFnZXMvQ291bnQgMS9JVFhUKDIuMS43KT4+CmVuZG9iago2IDAgb2JqCjw8L05hbWVzWyhKUl9QQUdFX0FOQ0hPUl8wXzEpIDUgMCBSXT4+CmVuZG9iago3IDAgb2JqCjw8L0Rlc3RzIDYgMCBSPj4KZW5kb2JqCjggMCBvYmoKPDwvTmFtZXMgNyAwIFIvVHlwZS9DYXRhbG9nL1BhZ2VzIDQgMCBSL1ZpZXdlclByZWZlcmVuY2VzPDwvUHJpbnRTY2FsaW5nL0FwcERlZmF1bHQ+Pj4+CmVuZG9iago5IDAgb2JqCjw8L01vZERhdGUoRDoyMDIwMDcwODE2NDIxNVopL0NyZWF0b3IoSmFzcGVyUmVwb3J0cyBMaWJyYXJ5IHZlcnNpb24gNi44LjEtM2Q0Yjg3MTE5YzgyN2JlMTM3NzZlNDUxZmIzNzM4MDYyZjg0YTg3ZCkvQ3JlYXRpb25EYXRlKEQ6MjAyMDA3MDgxNjQyMTVaKS9Qcm9kdWNlcihpVGV4dCAyLjEuNyBieSAxVDNYVCk+PgplbmRvYmoKeHJlZgowIDEwCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDc1MiAwMDAwMCBuIAowMDAwMDAxMDM5IDAwMDAwIG4gCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMTEyNyAwMDAwMCBuIAowMDAwMDAxMDA0IDAwMDAwIG4gCjAwMDAwMDExOTAgMDAwMDAgbiAKMDAwMDAwMTI0NCAwMDAwMCBuIAowMDAwMDAxMjc2IDAwMDAwIG4gCjAwMDAwMDEzNzkgMDAwMDAgbiAKdHJhaWxlcgo8PC9JbmZvIDkgMCBSL0lEIFs8MzlkODk2MTAwOTliYmQyMmU5ZGE4YjYxOTdiNWRmMzE+PDhmYzFkODQ2YTIwMmMzODBmNmRlZjA1MzkwY2NiOTM3Pl0vUm9vdCA4IDAgUi9TaXplIDEwPj4Kc3RhcnR4cmVmCjE1NzUKJSVFT0YK

    This is the output produced by utoa function:

    JVBERi0xLjUKJeLjz9MKMyAwIG9iago8PC9GaWx0ZXIvRmxhdGVEZWNvZGUvTGVuZ3RoIDY3MD4+c3RyZWFtCnicvVjLctMwFN37K+6yXdSRbD3ZQR8zZYCBjmFDWWRsOTUkUXHczuTvkZS4pSFYSuXJJp3JHOmcc1+6KQIMZxgQMJyZz3KR/E7eFUnOgHIGRZVcFsmXJIP39luLQ9Cji0UyucKAERR1cnJa/LTYZ4i77K9DGEkEVJKUkqejmT2KHKCdJSeIT5CYZChD9jYEsz03fv9h/lZO0RAX8XGdt2raqepNJBMFykiKWU+T7dDcqPphWa0iWXieA83lMUInEPJQFTo2aCKnx7KTMR/VB11Ou0YvY03lmY/p7XwOPVtsRfi4Prf6salUG+vKGz5rqieLNSWxj+3rKt6SpCGeLFN0kriPaTMe4MKMouhMCd+MuGr1IowlsASJHCzB6Xqhlh18VN2djh60GPv4XCW+4IzNnx0eYR7PTQJnul1HDxFxiMsta6PGKFSvUdVCsb6PrlPpTeT1spw/VAq+6aZaxQ+wgIhGrxvIR/JJH9p4KCVUCLOUpZwRbsCpRFLYyyxXZifzmXlHW5XUQ9KEXU4I9w+hXt9T8ZPUTBRithtC7clnvJ1W47nh6AA7xgeRHjuXda3KrnlUu46EPI4jnG8yZMoiKEUWPuioXxrGk5j1EnGQxMwrsV8BxpOYk61EFiTRwQcl2hd9xCZEW3k0qHAdfDiCdsKOp4+xTV/xIHkOHTAk4PpixM7fFqEISjD31+DmWdxte3dwT9NvdoTx7Ai8tRMUcYd+jR13cI+dfgUZz5BEh5SQQw8aMj+5q8ZuLe0/j407vMeUXThGNMQPKTiH9vUE3J6Ud6r8dXs64vuB6GEPiMMPKi10N53Dy4c+VOj/V6BXrX9Ga87ZYFTvdduBkxz97xnGUskNRT7YaDMFOHbPNAN+mAZ0HcjyB+XaEYIKZW5kc3RyZWFtCmVuZG9iagoxIDAgb2JqCjw8L1RhYnMvUy9Hcm91cDw8L1MvVHJhbnNwYXJlbmN5L1R5cGUvR3JvdXAvQ1MvRGV2aWNlUkdCPj4vQ29udGVudHMgMyAwIFIvVHlwZS9QYWdlL1Jlc291cmNlczw8L0NvbG9yU3BhY2U8PC9DUy9EZXZpY2VSR0I+Pi9Qcm9jU2V0IFsvUERGIC9UZXh0IC9JbWFnZUIgL0ltYWdlQyAvSW1hZ2VJXS9Gb250PDwvRjEgMiAwIFI+Pj4+L1BhcmVudCA0IDAgUi9Sb3RhdGUgOTAvTWVkaWFCb3hbMCAwIDYxMiAxMTYwXT4+CmVuZG9iago1IDAgb2JqClsxIDAgUi9YWVogMCA2MjIgMF0KZW5kb2JqCjIgMCBvYmoKPDwvU3VidHlwZS9UeXBlMS9UeXBlL0ZvbnQvQmFzZUZvbnQvSGVsdmV0aWNhL0VuY29kaW5nL1dpbkFuc2lFbmNvZGluZz4+CmVuZG9iago0IDAgb2JqCjw8L0tpZHNbMSAwIFJdL1R5cGUvUGFnZXMvQ291bnQgMS9JVFhUKDIuMS43KT4+CmVuZG9iago2IDAgb2JqCjw8L05hbWVzWyhKUl9QQUdFX0FOQ0hPUl8wXzEpIDUgMCBSXT4+CmVuZG9iago3IDAgb2JqCjw8L0Rlc3RzIDYgMCBSPj4KZW5kb2JqCjggMCBvYmoKPDwvTmFtZXMgNyAwIFIvVHlwZS9DYXRhbG9nL1BhZ2VzIDQgMCBSL1ZpZXdlclByZWZlcmVuY2VzPDwvUHJpbnRTY2FsaW5nL0FwcERlZmF1bHQ+Pj4+CmVuZG9iago5IDAgb2JqCjw8L01vZERhdGUoRDoyMDIwMDcwODE2NDIxNVopL0NyZWF0b3IoSmFzcGVyUmVwb3J0cyBMaWJyYXJ5IHZlcnNpb24gNi44LjEtM2Q0Yjg3MTE5YzgyN2JlMTM3NzZlNDUxZmIzNzM4MDYyZjg0YTg3ZCkvQ3JlYXRpb25EYXRlKEQ6MjAyMDA3MDgxNjQyMTVaKS9Qcm9kdWNlcihpVGV4dCAyLjEuNyBieSAxVDNYVCk+PgplbmRvYmoKeHJlZgowIDEwCjAwMDAwMDAwMDAgNjU1MzUgZiAKMDAwMDAwMDc1MiAwMDAwMCBuIAowMDAwMDAxMDM5IDAwMDAwIG4gCjAwMDAwMDAwMTUgMDAwMDAgbiAKMDAwMDAwMTEyNyAwMDAwMCBuIAowMDAwMDAxMDA0IDAwMDAwIG4gCjAwMDAwMDExOTAgMDAwMDAgbiAKMDAwMDAwMTI0NCAwMDAwMCBuIAowMDAwMDAxMjc2IDAwMDAwIG4gCjAwMDAwMDEzNzkgMDAwMDAgbiAKdHJhaWxlcgo8PC9JbmZvIDkgMCBSL0lEIFs8MzlkODk2MTAwOTliYmQyMmU5ZGE4YjYxOTdiNWRmMzE+PDhmYzFkODQ2YTIwMmMzODBmNmRlZjA1MzkwY2NiOTM3Pl0vUm9vdCA4IDAgUi9TaXplIDEwPj4Kc3RhcnR4cmVmCjE1NzUKJSVFT0YK

    Do you know why they would be different?
    • Juan,
      I'm sorry, i seem to have miscopied the second base64. This is the output produced by utoa() function:

      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c3BlclJlcG9ydHMgTGlicmFyeSB2ZXJzaW9uIDYuOC4xLTNkNGI4NzExOWM4MjdiZTEzNzc2ZTQ1MWZiMzczODA2MmY4NGE4N2QpL0NyZWF0aW9uRGF0ZShEOjIwMjAwNzA4MTY0MjE1WikvUHJvZHVjZXIoaVRleHQgMi4xLjcgYnkgMVQzWFQpPj4KZW5kb2JqCnhyZWYKMCAxMAowMDAwMDAwMDAwIDY1NTM1IGYgCjAwMDAwMDA3NTIgMDAwMDAgbiAKMDAwMDAwMTAzOSAwMDAwMCBuIAowMDAwMDAwMDE1IDAwMDAwIG4gCjAwMDAwMDExMjcgMDAwMDAgbiAKMDAwMDAwMTAwNCAwMDAwMCBuIAowMDAwMDAxMTkwIDAwMDAwIG4gCjAwMDAwMDEyNDQgMDAwMDAgbiAKMDAwMDAwMTI3NiAwMDAwMCBuIAowMDAwMDAxMzc5IDAwMDAwIG4gCnRyYWlsZXIKPDwvSW5mbyA5IDAgUi9JRCBbPDM5ZDg5NjEwMDk5YmJkMjJlOWRhOGI2MTk3YjVkZjMxPjw4ZmMxZDg0NmEyMDJjMzgwZjZkZWYwNTM5MGNjYjkzNz5dL1Jvb3QgOCAwIFIvU2l6ZSAxMD4+CnN0YXJ0eHJlZgoxNTc1CiUlRU9G"
Add new comment

If you have any questions, remarks, need help, or just like this page, please feel free to let me know by leaving a comment using the form bellow.
I will be happy to read every comment and, if necessary, I will do my best to respond as quickly as possible. Of course, spammers are welcome only as readers.