# Decode Base64 as unicode string

**URL:** <https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515>\
**Category:** General\
**Created:** [11 April 2025 09:23 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515 "2025-04-11T09:23:14Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [11 April 2025 09:23 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/1 "2025-04-11T09:23:14Z")

</div>

I'm playing around with Base64 encoding/decoding but I'm having a problem decoding a base64 encoded string with non 7bit char back into it's original unicode appearance

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/1/31de72fe96607995907a8140ba596933493686ee.png)

```auto
[{"id":"8285d46540f7a8ce","type":"inject","z":"6c0906b6354c0863","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"A £ B","payloadType":"str","x":170,"y":480,"wires":[["1daf2f2b67d5610d"]]},{"id":"1daf2f2b67d5610d","type":"base64","z":"6c0906b6354c0863","name":"","action":"","property":"payload","x":320,"y":480,"wires":[["f62b1b976c7ac977","cda376d17ff5dfd6"]]},{"id":"f62b1b976c7ac977","type":"debug","z":"6c0906b6354c0863","name":"debug 479","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":330,"y":530,"wires":[]},{"id":"cda376d17ff5dfd6","type":"base64","z":"6c0906b6354c0863","name":"","action":"b64","property":"payload","x":560,"y":480,"wires":[["fb6f76747517a14a"]]},{"id":"fb6f76747517a14a","type":"debug","z":"6c0906b6354c0863","name":"debug 480","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":570,"y":530,"wires":[]}]

```

Any ideas?  
[edit] And by ideas - I mean solutions 🙂 ]

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [11 April 2025 09:51 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/2 "2025-04-11T09:51:08Z")

</div>

After doing a [google search using 'valid base64 characters'](https://base64.guru/tools/validator) It looks like `£` is not a valid base64 character

Base64 is a scheme for converting binary data to printable ASCII characters, namely the upper- and lower-case Roman alphabet characters (A–Z, a–z), the numerals (0–9), and the "+" and "/" symbols, with the "=" symbol as a special suffix code.

Interestingly, the tool validator (in the link above) encode `A £ B` using 'Text to Base64' to `QSDCoyBC` and then if you use the 'Base64 to Text' option, it does convert it back to `A £ B`

It looks like the node just doesn't do a 'Base64 to text'.

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [11 April 2025 10:04 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/3 "2025-04-11T10:04:50Z")

</div>

Just for background - I've written several encoders/decoders in other languages 🙂 so I have a reasonable grasp of the protocol 🙂

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [11 April 2025 10:12 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/4 "2025-04-11T10:12:46Z")

</div>

I just took a look at the code (70-base64.js in node-red-node-base64) and one of the first lines is this:  
` var regexp = new RegExp('^[A-Za-z0-9+\/=]*$'); // check it only contains valid characters`  
So `£` is an invalid character in this node 😕

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [11 April 2025 10:19 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/5 "2025-04-11T10:19:44Z")

</div>

I think you are mixing up the difference between the input string and the base64 representation of it.

The base64 encoding "QSDCoyBC" doesn't contain a £

The way an encoder works (99% of time) is to convert a string into the UTF-8 byte representation so that all the data is a buffer/list of 0-255 byte values.

So a "£" (which has a unicode value of 163) gets converted to its UTF-8 representation [194,163] before being encoded to Base64

[edit] I've realised that "£" is not a good example 🙂  
A better one is "𐀀" which has a unicode value of 65536 - it's UTF-8 representation is [240, 144, 128, 128]

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [11 April 2025 11:24 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/6 "2025-04-11T11:24:52Z")

</div>

Maybe @dceejay will take a look at this.

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [12 April 2025 08:41 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/7 "2025-04-12T08:41:17Z")

</div>

I've come up with a solution

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/1/a1fcb21d6e796905f0cfa1986d1a2c975a7ae03b.png)

```auto
[{"id":"8285d46540f7a8ce","type":"inject","z":"6c0906b6354c0863","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"A £ B","payloadType":"str","x":120,"y":480,"wires":[["1daf2f2b67d5610d"]]},{"id":"1daf2f2b67d5610d","type":"base64","z":"6c0906b6354c0863","name":"","action":"","property":"payload","x":330,"y":480,"wires":[["f62b1b976c7ac977","cda376d17ff5dfd6","7a462bc3a020418d"]]},{"id":"f62b1b976c7ac977","type":"debug","z":"6c0906b6354c0863","name":"debug 479","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":320,"y":530,"wires":[]},{"id":"cda376d17ff5dfd6","type":"base64","z":"6c0906b6354c0863","name":"","action":"b64","property":"payload","x":560,"y":480,"wires":[["fb6f76747517a14a"]]},{"id":"fb6f76747517a14a","type":"debug","z":"6c0906b6354c0863","name":"debug 480","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":570,"y":530,"wires":[]},{"id":"692f795809e9cf96","type":"buffer-parser","z":"6c0906b6354c0863","name":"","data":"payload","dataType":"msg","specification":"spec","specificationType":"ui","items":[{"type":"utf8","name":"item1","offset":0,"length":-1,"offsetbit":0,"scale":"1","mask":""}],"swap1":"","swap2":"","swap3":"","swap1Type":"swap","swap2Type":"swap","swap3Type":"swap","msgProperty":"payload","msgPropertyType":"str","resultType":"value","resultTypeType":"return","multipleResult":true,"fanOutMultipleResult":false,"setTopic":true,"outputs":1,"x":780,"y":590,"wires":[["9826d91e501fb02d"]]},{"id":"b509edea0dd49467","type":"debug","z":"6c0906b6354c0863","name":"debug 481","active":false,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":570,"y":640,"wires":[]},{"id":"6fe53ce00e711715","type":"base64","z":"6c0906b6354c0863","name":"","action":"","property":"payload","x":560,"y":590,"wires":[["692f795809e9cf96","b509edea0dd49467"]]},{"id":"9826d91e501fb02d","type":"debug","z":"6c0906b6354c0863","name":"debug 482","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"msg","x":1000,"y":590,"wires":[]},{"id":"7a462bc3a020418d","type":"junction","z":"6c0906b6354c0863","x":440,"y":590,"wires":[["6fe53ce00e711715"]]}]

```

The buffer parser is configured like this

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/c/0c502eedf125827a8302db67be84f3af2783515d.png)

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [14 April 2025 15:23 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/8 "2025-04-14T15:23:54Z")

</div>

Hi - just back from a trip and catching up.... so hmmmm yes - the behaviour is not quite ideal is it...  
What is actually wrong is that the description of the option says "Convert Base64 to String" and then it proceeds to converts it toString("binary") rather than just toString() - which defaults to utf8...

Of course the whole point of base64 encoding is to be able to get transmit a binary payload so is really meant for true binary and if you use the default Convert Buffer \<-\> Base64 option - then you do get a binary buffer back that you can then toString yourself correctly...

So -I think I should just correct the behaviour of that option to just toString('utf8') it to a string as the label suggests and implies - As this would potentially be a breaking change for some people I would have to bump the node to v1.0

Thoughts please

 ![Screenshot 2025-04-14 at 16.26.35](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/c/3cdab717c246d834df66b4162bb530d4dcf3fe4b.png)

```auto
[{"id":"8285d46540f7a8ce","type":"inject","z":"4adb98c6.b11238","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"A £ B","payloadType":"str","x":110,"y":640,"wires":[["1daf2f2b67d5610d"]]},{"id":"1daf2f2b67d5610d","type":"base64","z":"4adb98c6.b11238","name":"","action":"","property":"payload","x":260,"y":640,"wires":[["f62b1b976c7ac977","cda376d17ff5dfd6"]]},{"id":"f62b1b976c7ac977","type":"debug","z":"4adb98c6.b11238","name":"debug 479","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":270,"y":690,"wires":[]},{"id":"cda376d17ff5dfd6","type":"base64","z":"4adb98c6.b11238","name":"","action":"","property":"payload","x":500,"y":640,"wires":[["fb6f76747517a14a","bede4c28c2bf6249"]]},{"id":"fb6f76747517a14a","type":"debug","z":"4adb98c6.b11238","name":"debug 480","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":510,"y":690,"wires":[]},{"id":"c7a6bf1eeb447772","type":"inject","z":"4adb98c6.b11238","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"A £ B","payloadType":"str","x":110,"y":510,"wires":[["8cae002f0395ed64"]]},{"id":"8cae002f0395ed64","type":"base64","z":"4adb98c6.b11238","name":"","action":"str","property":"payload","x":260,"y":510,"wires":[["b9fb9006e6440745","fb9bc53d81ac7bd8"]]},{"id":"b9fb9006e6440745","type":"debug","z":"4adb98c6.b11238","name":"debug 481","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":270,"y":560,"wires":[]},{"id":"fb9bc53d81ac7bd8","type":"base64","z":"4adb98c6.b11238","name":"","action":"b64","property":"payload","x":500,"y":510,"wires":[["573f50d928f5b6c4"]]},{"id":"573f50d928f5b6c4","type":"debug","z":"4adb98c6.b11238","name":"debug 482","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":510,"y":560,"wires":[]},{"id":"bede4c28c2bf6249","type":"function","z":"4adb98c6.b11238","name":"function 2","func":"msg.payload = msg.payload.toString()\nreturn msg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":680,"y":640,"wires":[["3ecfea4c43cfb1ec"]]},{"id":"3ecfea4c43cfb1ec","type":"debug","z":"4adb98c6.b11238","name":"debug 483","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":730,"y":700,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [14 April 2025 15:51 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/9 "2025-04-14T15:51:53Z")

</div>

> [@dceejay](#):
>
> So - I think I should just correct the behaviour of that option to just toString('utf8') it to a string as the label suggests and implies

That would be great 🙂

---

<div class="post-metadata">

**Author:** ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)\
**Post date:** [14 April 2025 16:51 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/10 "2025-04-14T16:51:30Z")

</div>

Published as version 1.0

---

<div class="post-metadata">

**Author:** ![cymplecy](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cymplecy/32/2773_2.png) [@cymplecy](https://discourse.nodered.org/u/cymplecy)\
**Post date:** [14 April 2025 17:16 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/11 "2025-04-14T17:16:26Z")

</div>

Looking good 🙂

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/8/08075f8a6bf3f9a89d46de57dc4723acd3e8faa9.png)

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [28 April 2025 17:17 UTC](https://discourse.nodered.org/t/decode-base64-as-unicode-string/96515/12 "2025-04-28T17:17:18Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
