{"id":22894244,"url":"https://github.com/clearcodehq/querystringsafe_base64","last_synced_at":"2025-06-21T04:11:04.288Z","repository":{"id":52417264,"uuid":"51291720","full_name":"ClearcodeHQ/querystringsafe_base64","owner":"ClearcodeHQ","description":"Encoding and decoding arbitrary strings into strings that are safe to put into a URL query param.","archived":false,"fork":false,"pushed_at":"2021-04-29T20:06:40.000Z","size":39,"stargazers_count":2,"open_issues_count":2,"forks_count":2,"subscribers_count":13,"default_branch":"master","last_synced_at":"2025-06-09T05:50:01.045Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ClearcodeHQ.png","metadata":{"files":{"readme":"README.rst","changelog":"CHANGES.rst","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-02-08T10:32:58.000Z","updated_at":"2019-07-31T14:56:25.000Z","dependencies_parsed_at":"2022-09-10T11:51:03.539Z","dependency_job_id":null,"html_url":"https://github.com/ClearcodeHQ/querystringsafe_base64","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"purl":"pkg:github/ClearcodeHQ/querystringsafe_base64","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClearcodeHQ%2Fquerystringsafe_base64","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClearcodeHQ%2Fquerystringsafe_base64/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClearcodeHQ%2Fquerystringsafe_base64/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClearcodeHQ%2Fquerystringsafe_base64/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ClearcodeHQ","download_url":"https://codeload.github.com/ClearcodeHQ/querystringsafe_base64/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ClearcodeHQ%2Fquerystringsafe_base64/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261060173,"owners_count":23103987,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-12-13T23:17:17.337Z","updated_at":"2025-06-21T04:10:59.243Z","avatar_url":"https://github.com/ClearcodeHQ.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":".. image:: https://travis-ci.org/ClearcodeHQ/querystringsafe_base64.svg?branch=v1.2.0\n    :target: https://travis-ci.org/ClearcodeHQ/querystringsafe_base64\n    :alt: Tests\n\n.. image:: https://coveralls.io/repos/ClearcodeHQ/querystringsafe_base64/badge.png?branch=v1.2.0\n    :target: https://coveralls.io/r/ClearcodeHQ/querystringsafe_base64?branch=v1.2.0\n    :alt: Coverage Status\n\nQuery string safe Base64\n========================\n\nEncoding and decoding arbitrary strings into strings that are safe to put into a URL query param.\n\nThe problem\n-----------\n\n`urlsafe_b64encode` and `urlsafe_b64decode` from base64 are not enough because they leave `=` used for padding chars unquoted:\n\n.. code-block:: python\n\n    import base64\n\n    base64.urlsafe_b64encode('a')\n    'YQ=='\n\nAnd there are 2 problems with that\n\nI. `=` sign gets quoted:\n\n.. code-block:: python\n\n    import urllib\n\n    urllib.quote('=')\n    '%3D'\n\nII. Some libraries tolerate the `=` in query string values:\n\n.. code-block:: python\n\n    from urlparse import urlsplit, parse_qs\n\n    parse_qs(urlsplit('http://aaa.com/asa?q=AAAA=BBBB=CCCC').query)\n    {'q': ['AAAA=BBBB=CCCC']}\n\nbut the RFC 3986 underspecifies the query string so we cannot rely on `=` chars being handled by all web applications as it is done by urlparse.\n\nTherefore we consider chars: `['+', '/', '=']` unsafe and we replace them with `['-', '_', '.']`.\nCharacters `+` and `/` are already handled by `urlsafe_*` functions from base64 so only `=` is left.\nSince the `=` is used exclusively for padding, we simply remove it, and re-attach the padding during decoding.\nBecause of that, `querystringsafe_base64` is able to decode padded and unpadded string.\n\nThe solution\n------------\n\n.. code-block:: python\n\n    import querystringsafe_base64\n\n    querystringsafe_base64.encode(b'foo-bar')\n    b'Zm9vLWJhcg'\n\n    querystringsafe_base64.decode(b'Zm9vLWJhcg..')\n    b'foo-bar'\n\n    querystringsafe_base64.decode(b'Zm9vLWJhcg')\n    b'foo-bar'\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclearcodehq%2Fquerystringsafe_base64","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fclearcodehq%2Fquerystringsafe_base64","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fclearcodehq%2Fquerystringsafe_base64/lists"}