Converting string to web-safe Base64 format
Asked Answered
S

4

6

I am testing how to update user picture using the Admin SDK Directory Service with Google Apps Scripts with the following function:

function updatePhoto(){
  var fileId = 'XXXXXXXXXXXXXXXXXXX';
  var b = DocsList.getFileById(fileId).getBlob();
  var encoded = Utilities.base64Encode(b.getBytes());

  encoded = encoded.replace(/\//g,'_').replace(/\+/g,'-').replace(/\=/g,'*');
  AdminDirectory.Users.Photos.update({
    "photoData": encoded },'[email protected]');
}

However, it doesn't always work. Whenever there is padding in the base64 encoded string, it fails. Referring to Google's document (https://developers.google.com/admin-sdk/directory/v1/reference/users/photos/update), I am a bit confused with the descriptions. It says:

  1. The equals sign (=) character is replaced with the asterisk (*).
  2. For padding, the period (.) character is used instead of the RFC-4648 baseURL definition which uses the equals sign (=) for padding. This is done to simplify URL-parsing.

What should be actually done? (=) is used for padding in Base64. So, should I use (*) or (.)? I did try to replace (=) with (.) but no luck.

Can anyone help?


It is so strange. It works when i do not replace (=).

function updatePhoto(){
  var fileId = 'XXXXXXXXXXXXXXXXXXX';
  var b = DocsList.getFileById(fileId).getBlob();
  var encoded = Utilities.base64Encode(b.getBytes());

  encoded = encoded.replace(/\//g,'_').replace(/\+/g,'-');
  AdminDirectory.Users.Photos.update({
    "photoData": encoded },'[email protected]');

}

Stoa answered 2/3, 2014 at 14:23 Comment(0)
B
8

The API requires you to use URL-safe base64 encoding. After doing the base64 encoding, try replacing / with _ and + with -. Details at:

https://developers.google.com/admin-sdk/directory/v1/reference/users/photos/update

Bandicoot answered 2/3, 2014 at 18:51 Comment(5)
Thanks a lot. It works. I got confused by that description and the error message. After adding the following line before the AdminDirectory line, it works. encoded = encoded.replace(/\//g,'_').replace(/\+/g,'-').replace(/\=/g,'*'); "Stoa
:) Oh. I just found that it doesn't work for all photos.Stoa
I just figured out the problem came from the padding. Whenever there is padding, it fails. I have edited the question accordingly.Stoa
This is so funny. I kinda solved that problem by simply leave (=) unchanged. Strange. encoded = encoded.replace(/\//g,'_').replace(/\+/g,'-');Stoa
what about the german characters like ä,ü,ö & ß?Gaynor
S
4

I know that this is quite old, but I'm working in something similar and I want to share my solution. You can use this function to convert your string to a base64safeurl string:

protected static string Base64ForUrlEncode(string str)
        {

            StringBuilder result = new StringBuilder(Convert.ToBase64String(Encoding.ASCII.GetBytes(str)).TrimEnd('='));
            result.Replace('+', '-');
            result.Replace('/', '_');
            return result.ToString();
        }

More info here: http://www.codeproject.com/Tips/76650/Base-base-url-base-url-and-z-base-encoding

Note: This is C# code, so this solution is for .NET developments.

Saddletree answered 24/9, 2014 at 14:5 Comment(8)
This only replaces first occurrence,the code in the comments does it globally.Pewter
Sorry, but I don't understand. Can you explain what do you mean with "first occurrence"?Kochi
result.Replace('+', '-'); replaces only first occurrence of +, if you want all the + in a string to be replaced you need to use the g flag like in the answer below (g comes for 'global')Pewter
.NET documentation says: "Returns a new string in which all occurrences of a specified string in the current instance are replaced with another specified string."Kochi
.NET framework is not javascript...Look at javascript documentation developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… see the 'g' flag.Pewter
I know. My solution is in .NET. Like I said in the answer, I just wanted to share it. Could be useful to someone. I should edit my answer and make clear that is C# code.Kochi
Actually, you should not post answers for different languages than the question is about. This is definitely not useful to someone who would find this question, looking for Javascript. Please pay close attention to what languages/tags are used in a question in the future.Mortimer
what about the german characters like ä,ü,ö & ß?Gaynor
L
2

To add to @Jay lee's and @Daniel Marin's answers:

if you are using Python to encode, you can use:

base64.urlsafe

function, and in Java, you can use:

Base64.encodeBase64URLSafeString(byte[] binaryData)
Laparotomy answered 11/11, 2015 at 16:53 Comment(0)
M
1

RFC 4648 specifies "web-safe" base64 and calls it "base64url": https://datatracker.ietf.org/doc/html/rfc4648#section-5

Mambo answered 11/5, 2021 at 8:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.