How to encode and decode Base64 and Base64Url in Flutter / Dart
Asked Answered
S

2

52

I want to encode the following string in Base64Url in Flutter and decode it in on a Dart server.

"username:password"

How do I do that? And how do I do it in Base64?

Stonefish answered 18/5, 2019 at 16:58 Comment(3)
Possible duplicate of How to pass basic auth credentials in API call for a Flutter mobile application?Shimberg
Also related How to native convert string -> base64 and base64 -> stringVermifuge
I would like to include Base64Url since sometimes it is a requirement. The linked questions, while useful, don't ask or answer that.Stonefish
S
137

The dart:convert library contains an encoder and decoder for Base64 and Base64Url. However, they encode and decode Lists of integers, so for strings you also need to encode and decode in UTF-8. Rather than doing these two encodings separately, you can combine them with fuse.

You need to have the following import:

import 'dart:convert';

Base64

String credentials = "username:password";
Codec<String, String> stringToBase64 = utf8.fuse(base64);
String encoded = stringToBase64.encode(credentials);      // dXNlcm5hbWU6cGFzc3dvcmQ=
String decoded = stringToBase64.decode(encoded);          // username:password

Note that this is equivalent to:

String encoded = base64.encode(utf8.encode(credentials)); // dXNlcm5hbWU6cGFzc3dvcmQ=
String decoded = utf8.decode(base64.decode(encoded));     // username:password

Base64Url

String credentials = "username:password";
Codec<String, String> stringToBase64Url = utf8.fuse(base64Url);
String encoded = stringToBase64Url.encode(credentials);      // dXNlcm5hbWU6cGFzc3dvcmQ=
String decoded = stringToBase64Url.decode(encoded);          // username:password

Again, this is equivalent to:

String encoded = base64Url.encode(utf8.encode(credentials)); // dXNlcm5hbWU6cGFzc3dvcmQ=
String decoded = utf8.decode(base64Url.decode(encoded));     // username:password

Notes

  • Base64 is encoding, not compression. It won't make your string shorter.
  • Base64 is encoding, not encryption. Anyone can decode and read it. Don't send private data over an open network even if it is encoded in Base64.

See also

Stonefish answered 18/5, 2019 at 16:58 Comment(10)
instead of constructs like utf8.decode(base64.decode(credentials)); use Codec::fuse() methodBritzka
@pskink, At first I couldn't wrap my mind around what was happening (the expanded form felt more readable), but then I realized that you didn't need to switch the order of utf8 and base64. You just use decode on the fused method. So, yes, much easier.Stonefish
this is because fuse() method docs say: "When encoding, the resulting codec encodes with this before encoding with other. When decoding, the resulting codec decodes with other before decoding with this."Britzka
btw fuse is not limited to two codecs - you can call multiple fuse methods to chain more than two codecsBritzka
@Britzka I also found this one: Base64Encoder().convert(credentials.codeUnits), where you can also do Base64Encoder.urlSafe(). What are your thoughts on this? It seems more readable to me.Stonefish
this is Base64Codec.encoder - the same like base64.encoderBritzka
is there a way to short the encoded String to only 8 characters?Chum
@carrasc0, Base 64 is only encoding. It isn't compression. If you want to make the encoded string shorter, then you need to limit the amount of information that you are encoding.Stonefish
@Stonefish what im trying to do is simple: In dart, take a string of an ObjectId make it half it size for external urls and then decoded in the app when the link is used. I want this to avoid to make the ids of my items public, but not idea how to make it so far, do you have any?Chum
@carrasc0, Base 64 also doesn't encrypt anything, so encoding something in Base 64 doesn't make it any less public. Anyone can decode it. As for your question, it is probably better to ask a new Stack Overflow question. But maybe you could use one of the short uuid packages like nanoid2 and then use a lookup table somewhere if you don't want to expose your internal ID.Stonefish
M
0
String text = 'Hello, Flutter!';

// Encode the string to Base64
String base64Encoded = base64Encode(utf8.encode(text));

print('Base64 Encoded: $base64Encoded');

it's that easy fellow flutter devs

Millwright answered 25/9 at 11:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.