Search code examples
c#phpurlencodeurl-encoding

Parsing C# UrlTokenEncode string with PHP


I have the following c# code that converts an image into a base64 encoded string using UrlTokenEncode:

        byte[] imageArray = System.IO.File.ReadAllBytes(note_path);
        string base64ImageRepresentation = HttpServerUtility.UrlTokenEncode(imageArray);

        byte[] data = Encoding.UTF8.GetBytes($"id={id}&apikey={apikey}&friend_ids={friend_ids}&ttl={ttl}&note={base64ImageRepresentation}");

        Console.Write(sendRequest("upload-note", data));
        Console.ReadLine();

I send this to my lamp server to be parsed via php. Obviously this doesn't work because of how UrlTokenEncode uses - for +, _ for /, and integer value for padding equals signs. I have the following code to overcome this:

                $request->note = str_replace('-', '+', str_replace('_', '/', $request->note));
                $lastCharacter = substr($request->note, -1);
                if($lastCharacter == 1 || $lastCharacter == 2){
                    $request->note = substr($request->note, 0, -$lastCharacter);
                    if($lastCharacter == 1){
                        $request->note = $request->note . '=';
                    } else {
                        $request->note = $request->note . '==';
                    }
                }

My concern for this process comes from the trailing equals signs. I read that there will only ever be 1 or 2 equals signs for padding, but can there ever be a case where there is no padding? If that were possible, then the last character of a string could potentially be any random integer value correct? If that is true then my current process for decoding in php will not work, since it assumes the last character will always be 1 or 2 and that that character will represent the number of equal signs needed...

If my process will not work, is there a better way to decode a c# UrlTokenEncode string with PHP?


Solution

  • To answer my above questions:

    1. There will only ever be 0, 1, or 2 equals signs for padding at the end of a base64 encoded string
    2. If there is no padding then 0 is appended to base64 string

    I created the following functions to convert a base64 string created via c#'s UrlTokenEncode method back to a regular base64 string, as well as convert from a regular base64 string to the format UrlTokenDecode expects.

    function convertToUrlTokenFormat($val){
    
        $padding = substr_count($val, '=');
        $val = str_replace('=', '', $val);
        $val .= $padding;
        $val = str_replace('+', '-', str_replace('/', '_', $val));
    
        return $val;
    
    }
    
    function convertFromUrlTokenFormat($val){
    
        $val = str_replace('-', '+', str_replace('_', '/', $val));
        $lastCharacter = substr($val, -1);
        $val = substr($val, 0, -1);
        switch($lastCharacter){
            case 1:
                $val = $val . "=";
                break;
            case 2:
                $val = $val . "==";
                break;
        }
    
        return $val;
    
    }