Normal base64-encoded data cannot be used directly in URLs without escaping the +, /, and = characters. There is a popular URL-safe variant of base64 that avoids this problem by replacing these characters. The + and / are replaced with - and _ respectively, while the = padding characters are omitted completely as the correct padding can always be recreated if you know the length of the data.

It is very easy to encode and decode strings in this format using the normal base64 encoding provided by Tcl's binary command, so long as you don't mind a second pass over the data. Given that URLs are typically short, this is often not a concern.

Here is a basic implementation in pure Tcl, which I've also uploaded to GitHub at

# base64url.tcl --
#       Implementation of the URL-safe Base64 variant described
#       in section 5 of RFC 4648.
# Copyright 2020 Neil Madden.
# See the file LICENSE.txt for license terms.

package require Tcl         8.6
package provide base64url   1.0.0

namespace eval ::base64url {
    namespace export encode decode
    namespace ensemble create

    proc encode data {
        string map {+ - / _ = ""} [binary encode base64 $data]

    proc decode str {
        binary decode base64 [pad [string map {- + _ /} $str]]

    proc pad str {
        return $str[padding $str]

    proc padding str {
        string repeat = [expr {(4 - [string length $str]) & 3}]