Codebase list python-unpaddedbase64 / 33a8abd
Update upstream source from tag 'upstream/2.1.0' Update to upstream version '2.1.0' with Debian dir 69870a9048f3c157ae1ffe461db2793cf413a42f Andrej Shadura 1 year, 11 months ago
15 changed file(s) with 162 addition(s) and 191 deletion(s). Raw diff Collapse all Expand all
0 [flake8]
1 max-line-length = 88
2 extend-ignore = E203, W503
0 name: Continuous Integration
1
2 on:
3 push:
4 branches: [ master ]
5 pull_request:
6 branches: [ master ]
7
8 jobs:
9 lint:
10 runs-on: ubuntu-latest
11
12 steps:
13 - uses: actions/checkout@v2
14 - name: Set up Python ${{ matrix.python-version }}
15 uses: actions/setup-python@v2
16 with:
17 python-version: '3.x'
18 - name: Install dependencies
19 run: |
20 python -m pip install --upgrade pip
21 python -m pip install flake8 black mypy
22 - name: Lint with flake8
23 run: |
24 flake8 unpaddedbase64/ tests/
25 - name: Lint with black
26 run: |
27 black --check --diff unpaddedbase64/ tests/
28 - name: Lint with mypy
29 run: |
30 mypy --strict unpaddedbase64/ tests/
31
32 test:
33 needs: lint
34 runs-on: ubuntu-latest
35 strategy:
36 matrix:
37 python-version: ['3.x', '3.6', 'pypy-3.6']
38
39 steps:
40 - uses: actions/checkout@v2
41 - name: Set up Python ${{ matrix.python-version }}
42 uses: actions/setup-python@v2
43 with:
44 python-version: ${{ matrix.python-version }}
45 - name: Test with unittest
46 run: |
47 python -m unittest --verbose
00 .coverage
11 .tox/
22 __pycache__/
3 unpaddedbase64.egg-info/
4 unpaddedbase64.pyc
5 build/
63 dist/
4 poetry.lock
+0
-15
.travis.yml less more
0 language: python
1 env:
2 - TOXENV=packaging
3 - TOXENV=pep8
4 - TOXENV=py3pep8
5 - TOXENV=py27
6 - TOXENV=py33
7 - TOXENV=py34
8 - TOXENV=pypy
9
10 install:
11 - pip install tox
12
13 script:
14 - tox
+0
-4
MANIFEST.in less more
0 include *.in
1 include *.py
2 include LICENSE
3 include tox.ini
00 Unpadded Base64
11 ===============
2
3 .. image:: https://img.shields.io/pypi/v/unpaddedbase64.svg
4 :target: https://pypi.python.org/pypi/unpaddedbase64/
5 :alt: Latest Version
6
7 .. image:: https://img.shields.io/travis/matrix-org/python-unpaddedbase64.svg
8 :target: https://travis-ci.org/matrix-org/python-unpaddedbase64
92
103 Encode and decode Base64 without "=" padding.
114
125 `RFC 4648`_ specifies that Base64 should be padded to a multiple of 4 bytes
13 using "=" characters. However this conveys no benefit so many protocols choose
14 to use Base64 without the "=" padding.
6 using "=" characters. However many protocols choose to omit the "=" padding.
157
168 .. _`RFC 4648`: https://tools.ietf.org/html/rfc4648
179
2012
2113 .. code:: bash
2214
23 pip install unpaddedbase64
15 python3 -m pip install unpaddedbase64
2416
2517 Using
2618 -----
2820 .. code:: python
2921
3022 import unpaddedbase64
31 assert (unpaddedbase64.encode_base64(b'\x00')) == u'AA'
32 assert (unpaddedbase64.decode_base64(u'AA')) == b'\x00'
23 assert (unpaddedbase64.encode_base64(b'\x00')) == 'AA'
24 assert (unpaddedbase64.decode_base64('AA')) == b'\x00'
0 [build-system]
1 requires = ["poetry_core>=1.0.0"]
2 build-backend = "poetry.core.masonry.api"
3
4 [tool.poetry]
5 name = "unpaddedbase64"
6 version = "2.1.0"
7 description = 'Encode and decode Base64 without "=" padding'
8 license = "Apache-2.0"
9 authors = [ "The Matrix.org Foundation C.I.C." ]
10 readme = "README.rst"
11 homepage = "https://github.com/matrix-org/python-unpaddedbase64"
12 keywords = ["base64"]
13
14 [tool.poetry.urls]
15 "Issue Tracker" = "https://github.com/matrix-org/python-unpaddedbase64/issues"
16
17 [tool.poetry.dependencies]
18 python = "^3.6"
19
20 [tool.poetry.dev-dependencies]
21 black = "*"
22 flake8 = "*"
23 mypy = "*"
+0
-49
setup.py less more
0 #!/usr/bin/env python
1
2 # Copyright 2015 OpenMarket Ltd
3 #
4 # Licensed under the Apache License, Version 2.0 (the "License");
5 # you may not use this file except in compliance with the License.
6 # You may obtain a copy of the License at
7 #
8 # http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 from setuptools import setup
17 from codecs import open
18 import os
19
20 here = os.path.abspath(os.path.dirname(__file__))
21
22
23 def read_file(path_segments):
24 """Read a UTF-8 file from the package. Takes a list of strings to join to
25 make the path"""
26 file_path = os.path.join(here, *path_segments)
27 with open(file_path, encoding="utf-8") as f:
28 return f.read()
29
30
31 def exec_file(path_segments, name):
32 """Extract a constant from a python file by looking for a line defining
33 the constant and executing it."""
34 result = {}
35 code = read_file(path_segments)
36 lines = [line for line in code.split('\n') if line.startswith(name)]
37 exec("\n".join(lines), result)
38 return result[name]
39
40
41 setup(
42 name="unpaddedbase64",
43 version=exec_file(("unpaddedbase64.py",), "__version__"),
44 py_modules=["unpaddedbase64"],
45 description="Unpadded Base64",
46 long_description=read_file(("README.rst",)),
47 keywords="base64",
48 )
+0
-41
test_unpaddedbase64.py less more
0 # Copyright 2015 OpenMarket Ltd
1 #
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at
5 #
6 # http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 from unpaddedbase64 import encode_base64, decode_base64
15 import unittest
16
17
18 class TestUnpaddedBase64(unittest.TestCase):
19
20 def test_encode(self):
21 self.assertEqual(encode_base64(b''), u'')
22 self.assertEqual(encode_base64(b'\x00'), u'AA')
23 self.assertEqual(encode_base64(b'\x00\x00'), u'AAA')
24 self.assertEqual(encode_base64(b'\x00\x00\x00'), u'AAAA')
25
26 def test_decode(self):
27 self.assertEqual(decode_base64(u''), b'')
28 self.assertEqual(decode_base64(u'AA'), b'\x00')
29 self.assertEqual(decode_base64(u'AAA'), b'\x00\x00')
30 self.assertEqual(decode_base64(u'AAAA'), b'\x00\x00\x00')
31 with self.assertRaises(Exception):
32 decode_base64(u'A')
33
34 def test_encode_urlunsafe_chars(self):
35 self.assertEqual(encode_base64(b'\xff\xe6\x9a'), u'/+aa')
36 self.assertEqual(encode_base64(b'\xff\xe6\x9a', True), u'_-aa')
37
38 def test_decode_urlunsafe_chars(self):
39 self.assertEqual(decode_base64(u'/+aa'), b'\xff\xe6\x9a')
40 self.assertEqual(decode_base64(u'_-aa'), b'\xff\xe6\x9a')
(New empty file)
0 # Copyright 2015 OpenMarket Ltd
1 # Copyright 2021 The Matrix.org Foundation C.I.C.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 from unpaddedbase64 import encode_base64, decode_base64
16 import unittest
17
18
19 class TestUnpaddedBase64(unittest.TestCase):
20 def test_encode(self) -> None:
21 self.assertEqual(encode_base64(b""), "")
22 self.assertEqual(encode_base64(b"\x00"), "AA")
23 self.assertEqual(encode_base64(b"\x00\x00"), "AAA")
24 self.assertEqual(encode_base64(b"\x00\x00\x00"), "AAAA")
25
26 def test_decode(self) -> None:
27 self.assertEqual(decode_base64(""), b"")
28 self.assertEqual(decode_base64("AA"), b"\x00")
29 self.assertEqual(decode_base64("AAA"), b"\x00\x00")
30 self.assertEqual(decode_base64("AAAA"), b"\x00\x00\x00")
31 with self.assertRaises(Exception):
32 decode_base64("A")
33
34 def test_encode_urlunsafe_chars(self) -> None:
35 self.assertEqual(encode_base64(b"\xff\xe6\x9a"), "/+aa")
36 self.assertEqual(encode_base64(b"\xff\xe6\x9a", True), "_-aa")
37
38 def test_decode_urlunsafe_chars(self) -> None:
39 self.assertEqual(decode_base64("/+aa"), b"\xff\xe6\x9a")
40 self.assertEqual(decode_base64("_-aa"), b"\xff\xe6\x9a")
+0
-27
tox.ini less more
0 [tox]
1 envlist = packaging, pep8, py3pep8, py27, py33, py34, pypy
2
3 [testenv]
4 deps =
5 coverage
6 pytest
7 commands =
8 coverage run --source unpaddedbase64 -m pytest
9 coverage report -m --fail-under 100
10
11 [testenv:packaging]
12 deps =
13 check-manifest
14 commands = check-manifest
15
16 [testenv:pep8]
17 basepython = python2.7
18 deps =
19 flake8
20 commands = flake8 .
21
22 [testenv:py3pep8]
23 basepython = python3.4
24 deps =
25 flake8
26 commands = flake8 .
0 # Copyright 2014, 2015 OpenMarket Ltd
1 # Copyright 2021 The Matrix.org Foundation C.I.C.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 import base64
16
17
18 def encode_base64(input_bytes: bytes, urlsafe: bool = False) -> str:
19 """Encode bytes as an unpadded base64 string."""
20
21 if urlsafe:
22 encode = base64.urlsafe_b64encode
23 else:
24 encode = base64.b64encode
25
26 output_bytes = encode(input_bytes)
27 output_string = output_bytes.decode("ascii")
28 return output_string.rstrip("=")
29
30
31 def decode_base64(input_string: str) -> bytes:
32 """Decode an unpadded standard or urlsafe base64 string to bytes."""
33
34 input_bytes = input_string.encode("ascii")
35 input_len = len(input_bytes)
36 padding = b"=" * (3 - ((input_len + 3) % 4))
37
38 # Passing altchars here allows decoding both standard and urlsafe base64
39 output_bytes = base64.b64decode(input_bytes + padding, altchars=b"-_")
40 return output_bytes
(New empty file)
+0
-40
unpaddedbase64.py less more
0 # Copyright 2014, 2015 OpenMarket Ltd
1 #
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at
5 #
6 # http://www.apache.org/licenses/LICENSE-2.0
7 #
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
13
14 import base64
15
16 __version__ = "1.1.0"
17
18
19 def encode_base64(input_bytes, urlsafe=False):
20 """Encode bytes as a base64 string without any padding."""
21
22 encode = base64.urlsafe_b64encode if urlsafe else base64.b64encode
23 output_bytes = encode(input_bytes)
24 output_string = output_bytes.decode("ascii")
25 return output_string.rstrip(u"=")
26
27
28 def decode_base64(input_string):
29 """Decode a base64 string to bytes inferring padding from the length of the
30 string."""
31
32 input_bytes = input_string.encode("ascii")
33 input_len = len(input_bytes)
34 padding = b"=" * (3 - ((input_len + 3) % 4))
35 decode = base64.b64decode
36 if u'-' in input_string or u'_' in input_string:
37 decode = base64.urlsafe_b64decode
38 output_bytes = decode(input_bytes + padding)
39 return output_bytes