pybase64 1.4.2__cp313-cp313-android_21_arm64_v8a.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pybase64/__init__.py +124 -0
- pybase64/__main__.py +292 -0
- pybase64/_fallback.py +167 -0
- pybase64/_license.py +61 -0
- pybase64/_license.pyi +1 -0
- pybase64/_pybase64.cpython-313-aarch64-linux-android.so +0 -0
- pybase64/_pybase64.pyi +16 -0
- pybase64/_typing.py +35 -0
- pybase64/_version.py +3 -0
- pybase64/py.typed +0 -0
- pybase64-1.4.2.dist-info/METADATA +306 -0
- pybase64-1.4.2.dist-info/RECORD +16 -0
- pybase64-1.4.2.dist-info/WHEEL +5 -0
- pybase64-1.4.2.dist-info/entry_points.txt +2 -0
- pybase64-1.4.2.dist-info/licenses/LICENSE +25 -0
- pybase64-1.4.2.dist-info/top_level.txt +1 -0
pybase64/__init__.py
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
4
|
+
|
|
5
|
+
from ._license import _license
|
|
6
|
+
from ._version import _version
|
|
7
|
+
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from ._typing import Buffer
|
|
10
|
+
|
|
11
|
+
try:
|
|
12
|
+
from ._pybase64 import (
|
|
13
|
+
_get_simd_flags_compile, # noqa: F401
|
|
14
|
+
_get_simd_flags_runtime, # noqa: F401
|
|
15
|
+
_get_simd_name,
|
|
16
|
+
_get_simd_path,
|
|
17
|
+
_set_simd_path, # noqa: F401
|
|
18
|
+
b64decode,
|
|
19
|
+
b64decode_as_bytearray,
|
|
20
|
+
b64encode,
|
|
21
|
+
b64encode_as_string,
|
|
22
|
+
encodebytes,
|
|
23
|
+
)
|
|
24
|
+
except ImportError:
|
|
25
|
+
from ._fallback import (
|
|
26
|
+
_get_simd_name,
|
|
27
|
+
_get_simd_path,
|
|
28
|
+
b64decode,
|
|
29
|
+
b64decode_as_bytearray,
|
|
30
|
+
b64encode,
|
|
31
|
+
b64encode_as_string,
|
|
32
|
+
encodebytes,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
__all__ = (
|
|
37
|
+
"b64decode",
|
|
38
|
+
"b64decode_as_bytearray",
|
|
39
|
+
"b64encode",
|
|
40
|
+
"b64encode_as_string",
|
|
41
|
+
"encodebytes",
|
|
42
|
+
"standard_b64decode",
|
|
43
|
+
"standard_b64encode",
|
|
44
|
+
"urlsafe_b64decode",
|
|
45
|
+
"urlsafe_b64encode",
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
__version__ = _version
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def get_license_text() -> str:
|
|
52
|
+
"""Returns pybase64 license information as a :class:`str` object.
|
|
53
|
+
|
|
54
|
+
The result includes libbase64 license information as well.
|
|
55
|
+
"""
|
|
56
|
+
return _license
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def get_version() -> str:
|
|
60
|
+
"""Returns pybase64 version as a :class:`str` object.
|
|
61
|
+
|
|
62
|
+
The result reports if the C extension is used or not.
|
|
63
|
+
e.g. `1.0.0 (C extension active - AVX2)`
|
|
64
|
+
"""
|
|
65
|
+
simd_name = _get_simd_name(_get_simd_path())
|
|
66
|
+
if simd_name != "fallback":
|
|
67
|
+
return f"{__version__} (C extension active - {simd_name})"
|
|
68
|
+
return f"{__version__} (C extension inactive)"
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def standard_b64encode(s: Buffer) -> bytes:
|
|
72
|
+
"""Encode bytes using the standard Base64 alphabet.
|
|
73
|
+
|
|
74
|
+
Argument ``s`` is a :term:`bytes-like object` to encode.
|
|
75
|
+
|
|
76
|
+
The result is returned as a :class:`bytes` object.
|
|
77
|
+
"""
|
|
78
|
+
return b64encode(s)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def standard_b64decode(s: str | Buffer) -> bytes:
|
|
82
|
+
"""Decode bytes encoded with the standard Base64 alphabet.
|
|
83
|
+
|
|
84
|
+
Argument ``s`` is a :term:`bytes-like object` or ASCII string to
|
|
85
|
+
decode.
|
|
86
|
+
|
|
87
|
+
The result is returned as a :class:`bytes` object.
|
|
88
|
+
|
|
89
|
+
A :exc:`binascii.Error` is raised if the input is incorrectly padded.
|
|
90
|
+
|
|
91
|
+
Characters that are not in the standard alphabet are discarded prior
|
|
92
|
+
to the padding check.
|
|
93
|
+
"""
|
|
94
|
+
return b64decode(s)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def urlsafe_b64encode(s: Buffer) -> bytes:
|
|
98
|
+
"""Encode bytes using the URL- and filesystem-safe Base64 alphabet.
|
|
99
|
+
|
|
100
|
+
Argument ``s`` is a :term:`bytes-like object` to encode.
|
|
101
|
+
|
|
102
|
+
The result is returned as a :class:`bytes` object.
|
|
103
|
+
|
|
104
|
+
The alphabet uses '-' instead of '+' and '_' instead of '/'.
|
|
105
|
+
"""
|
|
106
|
+
return b64encode(s, b"-_")
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def urlsafe_b64decode(s: str | Buffer) -> bytes:
|
|
110
|
+
"""Decode bytes using the URL- and filesystem-safe Base64 alphabet.
|
|
111
|
+
|
|
112
|
+
Argument ``s`` is a :term:`bytes-like object` or ASCII string to
|
|
113
|
+
decode.
|
|
114
|
+
|
|
115
|
+
The result is returned as a :class:`bytes` object.
|
|
116
|
+
|
|
117
|
+
A :exc:`binascii.Error` is raised if the input is incorrectly padded.
|
|
118
|
+
|
|
119
|
+
Characters that are not in the URL-safe base-64 alphabet, and are not
|
|
120
|
+
a plus '+' or slash '/', are discarded prior to the padding check.
|
|
121
|
+
|
|
122
|
+
The alphabet uses '-' instead of '+' and '_' instead of '/'.
|
|
123
|
+
"""
|
|
124
|
+
return b64decode(s, b"-_")
|
pybase64/__main__.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import base64
|
|
5
|
+
import sys
|
|
6
|
+
from base64 import b64decode as b64decodeValidate
|
|
7
|
+
from base64 import encodebytes as b64encodebytes
|
|
8
|
+
from collections.abc import Sequence
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
from timeit import default_timer as timer
|
|
11
|
+
from typing import TYPE_CHECKING, Any
|
|
12
|
+
|
|
13
|
+
import pybase64
|
|
14
|
+
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from pybase64._typing import Decode, Encode, EncodeBytes
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def bench_one(
|
|
20
|
+
duration: float,
|
|
21
|
+
data: bytes,
|
|
22
|
+
enc: Encode,
|
|
23
|
+
dec: Decode,
|
|
24
|
+
encbytes: EncodeBytes,
|
|
25
|
+
altchars: bytes | None = None,
|
|
26
|
+
validate: bool = False,
|
|
27
|
+
) -> None:
|
|
28
|
+
duration = duration / 2.0
|
|
29
|
+
|
|
30
|
+
if not validate and altchars is None:
|
|
31
|
+
number = 0
|
|
32
|
+
time = timer()
|
|
33
|
+
while True:
|
|
34
|
+
encodedcontent = encbytes(data)
|
|
35
|
+
number += 1
|
|
36
|
+
if timer() - time > duration:
|
|
37
|
+
break
|
|
38
|
+
iter = number
|
|
39
|
+
time = timer()
|
|
40
|
+
while iter > 0:
|
|
41
|
+
encodedcontent = encbytes(data)
|
|
42
|
+
iter -= 1
|
|
43
|
+
time = timer() - time
|
|
44
|
+
print(
|
|
45
|
+
"{:<32s} {:9.3f} MB/s ({:,d} bytes -> {:,d} bytes)".format(
|
|
46
|
+
encbytes.__module__ + "." + encbytes.__name__ + ":",
|
|
47
|
+
((number * len(data)) / (1024.0 * 1024.0)) / time,
|
|
48
|
+
len(data),
|
|
49
|
+
len(encodedcontent),
|
|
50
|
+
)
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
number = 0
|
|
54
|
+
time = timer()
|
|
55
|
+
while True:
|
|
56
|
+
encodedcontent = enc(data, altchars=altchars)
|
|
57
|
+
number += 1
|
|
58
|
+
if timer() - time > duration:
|
|
59
|
+
break
|
|
60
|
+
iter = number
|
|
61
|
+
time = timer()
|
|
62
|
+
while iter > 0:
|
|
63
|
+
encodedcontent = enc(data, altchars=altchars)
|
|
64
|
+
iter -= 1
|
|
65
|
+
time = timer() - time
|
|
66
|
+
print(
|
|
67
|
+
"{:<32s} {:9.3f} MB/s ({:,d} bytes -> {:,d} bytes)".format(
|
|
68
|
+
enc.__module__ + "." + enc.__name__ + ":",
|
|
69
|
+
((number * len(data)) / (1024.0 * 1024.0)) / time,
|
|
70
|
+
len(data),
|
|
71
|
+
len(encodedcontent),
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
number = 0
|
|
76
|
+
time = timer()
|
|
77
|
+
while True:
|
|
78
|
+
decodedcontent = dec(encodedcontent, altchars=altchars, validate=validate)
|
|
79
|
+
number += 1
|
|
80
|
+
if timer() - time > duration:
|
|
81
|
+
break
|
|
82
|
+
iter = number
|
|
83
|
+
time = timer()
|
|
84
|
+
while iter > 0:
|
|
85
|
+
decodedcontent = dec(encodedcontent, altchars=altchars, validate=validate)
|
|
86
|
+
iter -= 1
|
|
87
|
+
time = timer() - time
|
|
88
|
+
print(
|
|
89
|
+
"{:<32s} {:9.3f} MB/s ({:,d} bytes -> {:,d} bytes)".format(
|
|
90
|
+
dec.__module__ + "." + dec.__name__ + ":",
|
|
91
|
+
((number * len(data)) / (1024.0 * 1024.0)) / time,
|
|
92
|
+
len(encodedcontent),
|
|
93
|
+
len(data),
|
|
94
|
+
)
|
|
95
|
+
)
|
|
96
|
+
assert decodedcontent == data
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def readall(file: str) -> bytes:
|
|
100
|
+
if file == "-":
|
|
101
|
+
return sys.stdin.buffer.read()
|
|
102
|
+
return Path(file).read_bytes()
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def writeall(file: str, data: bytes) -> None:
|
|
106
|
+
if file == "-":
|
|
107
|
+
sys.stdout.buffer.write(data)
|
|
108
|
+
else:
|
|
109
|
+
Path(file).write_bytes(data)
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def benchmark(duration: float, input: str) -> None:
|
|
113
|
+
print(__package__ + " " + pybase64.get_version())
|
|
114
|
+
data = readall(input)
|
|
115
|
+
for altchars in [None, b"-_"]:
|
|
116
|
+
for validate in [False, True]:
|
|
117
|
+
print(f"bench: altchars={altchars!r:s}, validate={validate!r:s}")
|
|
118
|
+
bench_one(
|
|
119
|
+
duration,
|
|
120
|
+
data,
|
|
121
|
+
pybase64.b64encode,
|
|
122
|
+
pybase64.b64decode,
|
|
123
|
+
pybase64.encodebytes,
|
|
124
|
+
altchars,
|
|
125
|
+
validate,
|
|
126
|
+
)
|
|
127
|
+
bench_one(
|
|
128
|
+
duration,
|
|
129
|
+
data,
|
|
130
|
+
base64.b64encode,
|
|
131
|
+
b64decodeValidate,
|
|
132
|
+
b64encodebytes,
|
|
133
|
+
altchars,
|
|
134
|
+
validate,
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def encode(input: str, altchars: bytes | None, output: str) -> None:
|
|
139
|
+
data = readall(input)
|
|
140
|
+
data = pybase64.b64encode(data, altchars)
|
|
141
|
+
writeall(output, data)
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
def decode(input: str, altchars: bytes | None, validate: bool, output: str) -> None:
|
|
145
|
+
data = readall(input)
|
|
146
|
+
data = pybase64.b64decode(data, altchars, validate)
|
|
147
|
+
writeall(output, data)
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
class LicenseAction(argparse.Action):
|
|
151
|
+
def __init__(
|
|
152
|
+
self,
|
|
153
|
+
option_strings: Sequence[str],
|
|
154
|
+
dest: str,
|
|
155
|
+
license: str | None = None,
|
|
156
|
+
help: str | None = "show license information and exit",
|
|
157
|
+
):
|
|
158
|
+
super().__init__(
|
|
159
|
+
option_strings=option_strings,
|
|
160
|
+
dest=dest,
|
|
161
|
+
default=argparse.SUPPRESS,
|
|
162
|
+
nargs=0,
|
|
163
|
+
help=help,
|
|
164
|
+
)
|
|
165
|
+
self.license = license
|
|
166
|
+
|
|
167
|
+
def __call__(
|
|
168
|
+
self,
|
|
169
|
+
parser: argparse.ArgumentParser,
|
|
170
|
+
namespace: argparse.Namespace, # noqa: ARG002
|
|
171
|
+
values: str | Sequence[Any] | None, # noqa: ARG002
|
|
172
|
+
option_string: str | None = None, # noqa: ARG002
|
|
173
|
+
) -> None:
|
|
174
|
+
print(self.license)
|
|
175
|
+
parser.exit()
|
|
176
|
+
|
|
177
|
+
|
|
178
|
+
def check_file(value: str, is_input: bool) -> str:
|
|
179
|
+
if value == "-":
|
|
180
|
+
return value
|
|
181
|
+
path = Path(value)
|
|
182
|
+
if is_input:
|
|
183
|
+
return str(path.resolve(strict=True))
|
|
184
|
+
return str(path.parent.resolve(strict=True) / path.name)
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
def main(argv: Sequence[str] | None = None) -> None:
|
|
188
|
+
# main parser
|
|
189
|
+
parser = argparse.ArgumentParser(
|
|
190
|
+
prog=__package__, description=__package__ + " command-line tool."
|
|
191
|
+
)
|
|
192
|
+
parser.add_argument(
|
|
193
|
+
"-V",
|
|
194
|
+
"--version",
|
|
195
|
+
action="version",
|
|
196
|
+
version=__package__ + " " + pybase64.get_version(),
|
|
197
|
+
)
|
|
198
|
+
parser.add_argument("--license", action=LicenseAction, license=pybase64.get_license_text())
|
|
199
|
+
# create sub-parsers
|
|
200
|
+
subparsers = parser.add_subparsers(help="tool help")
|
|
201
|
+
# benchmark parser
|
|
202
|
+
benchmark_parser = subparsers.add_parser("benchmark", help="-h for usage")
|
|
203
|
+
benchmark_parser.add_argument(
|
|
204
|
+
"-d",
|
|
205
|
+
"--duration",
|
|
206
|
+
metavar="D",
|
|
207
|
+
dest="duration",
|
|
208
|
+
type=float,
|
|
209
|
+
default=1.0,
|
|
210
|
+
help="expected duration for a single encode or decode test",
|
|
211
|
+
)
|
|
212
|
+
benchmark_parser.register("type", "input file", lambda s: check_file(s, True))
|
|
213
|
+
benchmark_parser.add_argument(
|
|
214
|
+
"input", type="input file", help="input file used for the benchmark"
|
|
215
|
+
)
|
|
216
|
+
benchmark_parser.set_defaults(func=benchmark)
|
|
217
|
+
# encode parser
|
|
218
|
+
encode_parser = subparsers.add_parser("encode", help="-h for usage")
|
|
219
|
+
encode_parser.register("type", "input file", lambda s: check_file(s, True))
|
|
220
|
+
encode_parser.register("type", "output file", lambda s: check_file(s, False))
|
|
221
|
+
encode_parser.add_argument("input", type="input file", help="input file to be encoded")
|
|
222
|
+
group = encode_parser.add_mutually_exclusive_group()
|
|
223
|
+
group.add_argument(
|
|
224
|
+
"-u",
|
|
225
|
+
"--url",
|
|
226
|
+
action="store_const",
|
|
227
|
+
const=b"-_",
|
|
228
|
+
dest="altchars",
|
|
229
|
+
help="use URL encoding",
|
|
230
|
+
)
|
|
231
|
+
group.add_argument(
|
|
232
|
+
"-a",
|
|
233
|
+
"--altchars",
|
|
234
|
+
dest="altchars",
|
|
235
|
+
help="use alternative characters for encoding",
|
|
236
|
+
)
|
|
237
|
+
encode_parser.add_argument(
|
|
238
|
+
"-o",
|
|
239
|
+
"--output",
|
|
240
|
+
dest="output",
|
|
241
|
+
type="output file",
|
|
242
|
+
default="-",
|
|
243
|
+
help="encoded output file (default to stdout)",
|
|
244
|
+
)
|
|
245
|
+
encode_parser.set_defaults(func=encode)
|
|
246
|
+
# decode parser
|
|
247
|
+
decode_parser = subparsers.add_parser("decode", help="-h for usage")
|
|
248
|
+
decode_parser.register("type", "input file", lambda s: check_file(s, True))
|
|
249
|
+
decode_parser.register("type", "output file", lambda s: check_file(s, False))
|
|
250
|
+
decode_parser.add_argument("input", type="input file", help="input file to be decoded")
|
|
251
|
+
group = decode_parser.add_mutually_exclusive_group()
|
|
252
|
+
group.add_argument(
|
|
253
|
+
"-u",
|
|
254
|
+
"--url",
|
|
255
|
+
action="store_const",
|
|
256
|
+
const=b"-_",
|
|
257
|
+
dest="altchars",
|
|
258
|
+
help="use URL decoding",
|
|
259
|
+
)
|
|
260
|
+
group.add_argument(
|
|
261
|
+
"-a",
|
|
262
|
+
"--altchars",
|
|
263
|
+
dest="altchars",
|
|
264
|
+
help="use alternative characters for decoding",
|
|
265
|
+
)
|
|
266
|
+
decode_parser.add_argument(
|
|
267
|
+
"-o",
|
|
268
|
+
"--output",
|
|
269
|
+
dest="output",
|
|
270
|
+
type="output file",
|
|
271
|
+
default="-",
|
|
272
|
+
help="decoded output file (default to stdout)",
|
|
273
|
+
)
|
|
274
|
+
decode_parser.add_argument(
|
|
275
|
+
"--no-validation",
|
|
276
|
+
dest="validate",
|
|
277
|
+
action="store_false",
|
|
278
|
+
help="disable validation of the input data",
|
|
279
|
+
)
|
|
280
|
+
decode_parser.set_defaults(func=decode)
|
|
281
|
+
# ready, parse
|
|
282
|
+
if argv is None:
|
|
283
|
+
argv = sys.argv[1:]
|
|
284
|
+
if len(argv) == 0:
|
|
285
|
+
argv = ["-h"]
|
|
286
|
+
args = vars(parser.parse_args(args=argv))
|
|
287
|
+
func = args.pop("func")
|
|
288
|
+
func(**args)
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
if __name__ == "__main__":
|
|
292
|
+
main()
|
pybase64/_fallback.py
ADDED
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from base64 import b64decode as builtin_decode
|
|
4
|
+
from base64 import b64encode as builtin_encode
|
|
5
|
+
from base64 import encodebytes as builtin_encodebytes
|
|
6
|
+
from binascii import Error as BinAsciiError
|
|
7
|
+
from typing import TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
if TYPE_CHECKING:
|
|
10
|
+
from ._typing import Buffer
|
|
11
|
+
|
|
12
|
+
_bytes_types = (bytes, bytearray) # Types acceptable as binary data
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _get_simd_name(flags: int) -> str:
|
|
16
|
+
assert flags == 0
|
|
17
|
+
return "fallback"
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _get_simd_path() -> int:
|
|
21
|
+
return 0
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def _get_bytes(s: str | Buffer) -> bytes | bytearray:
|
|
25
|
+
if isinstance(s, str):
|
|
26
|
+
try:
|
|
27
|
+
return s.encode("ascii")
|
|
28
|
+
except UnicodeEncodeError:
|
|
29
|
+
msg = "string argument should contain only ASCII characters"
|
|
30
|
+
raise ValueError(msg) from None
|
|
31
|
+
if isinstance(s, _bytes_types):
|
|
32
|
+
return s
|
|
33
|
+
try:
|
|
34
|
+
mv = memoryview(s)
|
|
35
|
+
if not mv.c_contiguous:
|
|
36
|
+
msg = f"{s.__class__.__name__!r:s}: underlying buffer is not C-contiguous"
|
|
37
|
+
raise BufferError(msg)
|
|
38
|
+
return mv.tobytes()
|
|
39
|
+
except TypeError:
|
|
40
|
+
msg = (
|
|
41
|
+
"argument should be a bytes-like object or ASCII "
|
|
42
|
+
f"string, not {s.__class__.__name__!r:s}"
|
|
43
|
+
)
|
|
44
|
+
raise TypeError(msg) from None
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def b64decode(
|
|
48
|
+
s: str | Buffer, altchars: str | Buffer | None = None, validate: bool = False
|
|
49
|
+
) -> bytes:
|
|
50
|
+
"""Decode bytes encoded with the standard Base64 alphabet.
|
|
51
|
+
|
|
52
|
+
Argument ``s`` is a :term:`bytes-like object` or ASCII string to
|
|
53
|
+
decode.
|
|
54
|
+
|
|
55
|
+
Optional ``altchars`` must be a :term:`bytes-like object` or ASCII
|
|
56
|
+
string of length 2 which specifies the alternative alphabet used instead
|
|
57
|
+
of the '+' and '/' characters.
|
|
58
|
+
|
|
59
|
+
If ``validate`` is ``False`` (the default), characters that are neither in
|
|
60
|
+
the normal base-64 alphabet nor the alternative alphabet are discarded
|
|
61
|
+
prior to the padding check.
|
|
62
|
+
If ``validate`` is ``True``, these non-alphabet characters in the input
|
|
63
|
+
result in a :exc:`binascii.Error`.
|
|
64
|
+
|
|
65
|
+
The result is returned as a :class:`bytes` object.
|
|
66
|
+
|
|
67
|
+
A :exc:`binascii.Error` is raised if ``s`` is incorrectly padded.
|
|
68
|
+
"""
|
|
69
|
+
s = _get_bytes(s)
|
|
70
|
+
if altchars is not None:
|
|
71
|
+
altchars = _get_bytes(altchars)
|
|
72
|
+
if validate:
|
|
73
|
+
if len(s) % 4 != 0:
|
|
74
|
+
msg = "Incorrect padding"
|
|
75
|
+
raise BinAsciiError(msg)
|
|
76
|
+
result = builtin_decode(s, altchars, validate=False)
|
|
77
|
+
|
|
78
|
+
# check length of result vs length of input
|
|
79
|
+
expected_len = 0
|
|
80
|
+
if len(s) > 0:
|
|
81
|
+
padding = 0
|
|
82
|
+
# len(s) % 4 != 0 implies len(s) >= 4 here
|
|
83
|
+
if s[-2] == 61: # 61 == ord("=")
|
|
84
|
+
padding += 1
|
|
85
|
+
if s[-1] == 61:
|
|
86
|
+
padding += 1
|
|
87
|
+
expected_len = 3 * (len(s) // 4) - padding
|
|
88
|
+
if expected_len != len(result):
|
|
89
|
+
msg = "Non-base64 digit found"
|
|
90
|
+
raise BinAsciiError(msg)
|
|
91
|
+
return result
|
|
92
|
+
return builtin_decode(s, altchars, validate=False)
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def b64decode_as_bytearray(
|
|
96
|
+
s: str | Buffer, altchars: str | Buffer | None = None, validate: bool = False
|
|
97
|
+
) -> bytearray:
|
|
98
|
+
"""Decode bytes encoded with the standard Base64 alphabet.
|
|
99
|
+
|
|
100
|
+
Argument ``s`` is a :term:`bytes-like object` or ASCII string to
|
|
101
|
+
decode.
|
|
102
|
+
|
|
103
|
+
Optional ``altchars`` must be a :term:`bytes-like object` or ASCII
|
|
104
|
+
string of length 2 which specifies the alternative alphabet used instead
|
|
105
|
+
of the '+' and '/' characters.
|
|
106
|
+
|
|
107
|
+
If ``validate`` is ``False`` (the default), characters that are neither in
|
|
108
|
+
the normal base-64 alphabet nor the alternative alphabet are discarded
|
|
109
|
+
prior to the padding check.
|
|
110
|
+
If ``validate`` is ``True``, these non-alphabet characters in the input
|
|
111
|
+
result in a :exc:`binascii.Error`.
|
|
112
|
+
|
|
113
|
+
The result is returned as a :class:`bytearray` object.
|
|
114
|
+
|
|
115
|
+
A :exc:`binascii.Error` is raised if ``s`` is incorrectly padded.
|
|
116
|
+
"""
|
|
117
|
+
return bytearray(b64decode(s, altchars=altchars, validate=validate))
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
def b64encode(s: Buffer, altchars: str | Buffer | None = None) -> bytes:
|
|
121
|
+
"""Encode bytes using the standard Base64 alphabet.
|
|
122
|
+
|
|
123
|
+
Argument ``s`` is a :term:`bytes-like object` to encode.
|
|
124
|
+
|
|
125
|
+
Optional ``altchars`` must be a byte string of length 2 which specifies
|
|
126
|
+
an alternative alphabet for the '+' and '/' characters. This allows an
|
|
127
|
+
application to e.g. generate url or filesystem safe Base64 strings.
|
|
128
|
+
|
|
129
|
+
The result is returned as a :class:`bytes` object.
|
|
130
|
+
"""
|
|
131
|
+
mv = memoryview(s)
|
|
132
|
+
if not mv.c_contiguous:
|
|
133
|
+
msg = f"{s.__class__.__name__!r:s}: underlying buffer is not C-contiguous"
|
|
134
|
+
raise BufferError(msg)
|
|
135
|
+
if altchars is not None:
|
|
136
|
+
altchars = _get_bytes(altchars)
|
|
137
|
+
return builtin_encode(s, altchars)
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
def b64encode_as_string(s: Buffer, altchars: str | Buffer | None = None) -> str:
|
|
141
|
+
"""Encode bytes using the standard Base64 alphabet.
|
|
142
|
+
|
|
143
|
+
Argument ``s`` is a :term:`bytes-like object` to encode.
|
|
144
|
+
|
|
145
|
+
Optional ``altchars`` must be a byte string of length 2 which specifies
|
|
146
|
+
an alternative alphabet for the '+' and '/' characters. This allows an
|
|
147
|
+
application to e.g. generate url or filesystem safe Base64 strings.
|
|
148
|
+
|
|
149
|
+
The result is returned as a :class:`str` object.
|
|
150
|
+
"""
|
|
151
|
+
return b64encode(s, altchars).decode("ascii")
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
def encodebytes(s: Buffer) -> bytes:
|
|
155
|
+
"""Encode bytes into a bytes object with newlines (b'\\\\n') inserted after
|
|
156
|
+
every 76 bytes of output, and ensuring that there is a trailing newline,
|
|
157
|
+
as per :rfc:`2045` (MIME).
|
|
158
|
+
|
|
159
|
+
Argument ``s`` is a :term:`bytes-like object` to encode.
|
|
160
|
+
|
|
161
|
+
The result is returned as a :class:`bytes` object.
|
|
162
|
+
"""
|
|
163
|
+
mv = memoryview(s)
|
|
164
|
+
if not mv.c_contiguous:
|
|
165
|
+
msg = f"{s.__class__.__name__!r:s}: underlying buffer is not C-contiguous"
|
|
166
|
+
raise BufferError(msg)
|
|
167
|
+
return builtin_encodebytes(s)
|
pybase64/_license.py
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
_license = """pybase64
|
|
2
|
+
===============================================================================
|
|
3
|
+
BSD 2-Clause License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2017-2022, Matthieu Darbois
|
|
6
|
+
All rights reserved.
|
|
7
|
+
|
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
|
9
|
+
modification, are permitted provided that the following conditions are met:
|
|
10
|
+
|
|
11
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
12
|
+
list of conditions and the following disclaimer.
|
|
13
|
+
|
|
14
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
15
|
+
this list of conditions and the following disclaimer in the documentation
|
|
16
|
+
and/or other materials provided with the distribution.
|
|
17
|
+
|
|
18
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
19
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
20
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
21
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
22
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
23
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
24
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
25
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
26
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
27
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
28
|
+
===============================================================================
|
|
29
|
+
|
|
30
|
+
libbase64
|
|
31
|
+
===============================================================================
|
|
32
|
+
Copyright (c) 2005-2007, Nick Galbreath
|
|
33
|
+
Copyright (c) 2015-2018, Wojciech Muła
|
|
34
|
+
Copyright (c) 2016-2017, Matthieu Darbois
|
|
35
|
+
Copyright (c) 2013-2022, Alfred Klomp
|
|
36
|
+
All rights reserved.
|
|
37
|
+
|
|
38
|
+
Redistribution and use in source and binary forms, with or without
|
|
39
|
+
modification, are permitted provided that the following conditions are
|
|
40
|
+
met:
|
|
41
|
+
|
|
42
|
+
- Redistributions of source code must retain the above copyright notice,
|
|
43
|
+
this list of conditions and the following disclaimer.
|
|
44
|
+
|
|
45
|
+
- Redistributions in binary form must reproduce the above copyright
|
|
46
|
+
notice, this list of conditions and the following disclaimer in the
|
|
47
|
+
documentation and/or other materials provided with the distribution.
|
|
48
|
+
|
|
49
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
|
|
50
|
+
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
51
|
+
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
52
|
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
53
|
+
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
54
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
|
|
55
|
+
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
56
|
+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
57
|
+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
58
|
+
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
59
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
60
|
+
==========================================================================""" \
|
|
61
|
+
+ "====="
|
pybase64/_license.pyi
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
_license: str
|
|
Binary file
|
pybase64/_pybase64.pyi
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
from ._typing import Buffer
|
|
2
|
+
|
|
3
|
+
def _get_simd_flags_compile() -> int: ...
|
|
4
|
+
def _get_simd_flags_runtime() -> int: ...
|
|
5
|
+
def _get_simd_name(flags: int) -> str: ...
|
|
6
|
+
def _get_simd_path() -> int: ...
|
|
7
|
+
def _set_simd_path(flags: int) -> None: ...
|
|
8
|
+
def b64decode(
|
|
9
|
+
s: str | Buffer, altchars: str | Buffer | None = None, validate: bool = False
|
|
10
|
+
) -> bytes: ...
|
|
11
|
+
def b64decode_as_bytearray(
|
|
12
|
+
s: str | Buffer, altchars: str | Buffer | None = None, validate: bool = False
|
|
13
|
+
) -> bytearray: ...
|
|
14
|
+
def b64encode(s: Buffer, altchars: str | Buffer | None = None) -> bytes: ...
|
|
15
|
+
def b64encode_as_string(s: Buffer, altchars: str | Buffer | None = None) -> str: ...
|
|
16
|
+
def encodebytes(s: Buffer) -> bytes: ...
|
pybase64/_typing.py
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import sys
|
|
4
|
+
from typing import Protocol
|
|
5
|
+
|
|
6
|
+
if sys.version_info < (3, 12):
|
|
7
|
+
from typing_extensions import Buffer
|
|
8
|
+
else:
|
|
9
|
+
from collections.abc import Buffer
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class Decode(Protocol):
|
|
13
|
+
__name__: str
|
|
14
|
+
__module__: str
|
|
15
|
+
|
|
16
|
+
def __call__(
|
|
17
|
+
self, s: str | Buffer, altchars: str | Buffer | None = None, validate: bool = False
|
|
18
|
+
) -> bytes: ...
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class Encode(Protocol):
|
|
22
|
+
__name__: str
|
|
23
|
+
__module__: str
|
|
24
|
+
|
|
25
|
+
def __call__(self, s: Buffer, altchars: Buffer | None = None) -> bytes: ...
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class EncodeBytes(Protocol):
|
|
29
|
+
__name__: str
|
|
30
|
+
__module__: str
|
|
31
|
+
|
|
32
|
+
def __call__(self, s: Buffer) -> bytes: ...
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
__all__ = ("Buffer", "Decode", "Encode", "EncodeBytes")
|
pybase64/_version.py
ADDED
pybase64/py.typed
ADDED
|
File without changes
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pybase64
|
|
3
|
+
Version: 1.4.2
|
|
4
|
+
Summary: Fast Base64 encoding/decoding
|
|
5
|
+
Home-page: https://github.com/mayeut/pybase64
|
|
6
|
+
Author: Matthieu Darbois
|
|
7
|
+
License: BSD-2-Clause
|
|
8
|
+
Project-URL: Source, https://github.com/mayeut/pybase64
|
|
9
|
+
Project-URL: Tracker, https://github.com/mayeut/pybase64/issues
|
|
10
|
+
Project-URL: Documentation, https://pybase64.readthedocs.io/en/stable
|
|
11
|
+
Keywords: base64
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
15
|
+
Classifier: Topic :: Utilities
|
|
16
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
17
|
+
Classifier: Programming Language :: C
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/x-rst
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: classifier
|
|
31
|
+
Dynamic: description
|
|
32
|
+
Dynamic: description-content-type
|
|
33
|
+
Dynamic: home-page
|
|
34
|
+
Dynamic: keywords
|
|
35
|
+
Dynamic: license
|
|
36
|
+
Dynamic: license-file
|
|
37
|
+
Dynamic: project-url
|
|
38
|
+
Dynamic: requires-python
|
|
39
|
+
Dynamic: summary
|
|
40
|
+
|
|
41
|
+
.. SETUP VARIABLES
|
|
42
|
+
.. |license-status| image:: https://img.shields.io/badge/license-BSD%202--Clause-blue.svg
|
|
43
|
+
:target: https://github.com/mayeut/pybase64/blob/master/LICENSE
|
|
44
|
+
.. |pypi-status| image:: https://img.shields.io/pypi/v/pybase64.svg
|
|
45
|
+
:target: https://pypi.python.org/pypi/pybase64
|
|
46
|
+
.. |python-versions| image:: https://img.shields.io/pypi/pyversions/pybase64.svg
|
|
47
|
+
.. |rtd-status| image:: https://readthedocs.org/projects/pybase64/badge/?version=stable
|
|
48
|
+
:target: http://pybase64.readthedocs.io/en/stable/?badge=stable
|
|
49
|
+
:alt: Documentation Status
|
|
50
|
+
.. |gha-status| image:: https://github.com/mayeut/pybase64/workflows/Build%20and%20upload%20to%20PyPI/badge.svg
|
|
51
|
+
:target: https://github.com/mayeut/pybase64/actions?query=workflow%3A%22Build+and+upload+to+PyPI%22
|
|
52
|
+
.. |codecov-status| image:: https://codecov.io/gh/mayeut/pybase64/branch/master/graph/badge.svg
|
|
53
|
+
:target: https://codecov.io/gh/mayeut/pybase64/branch/master
|
|
54
|
+
.. END OF SETUP
|
|
55
|
+
|
|
56
|
+
Fast Base64 implementation
|
|
57
|
+
==========================
|
|
58
|
+
|
|
59
|
+
|license-status| |pypi-status| |python-versions| |rtd-status| |gha-status| |codecov-status|
|
|
60
|
+
|
|
61
|
+
This project is a wrapper on `libbase64 <https://github.com/aklomp/base64>`_.
|
|
62
|
+
|
|
63
|
+
It aims to provide a fast base64 implementation for base64 encoding/decoding.
|
|
64
|
+
|
|
65
|
+
Installation
|
|
66
|
+
============
|
|
67
|
+
|
|
68
|
+
.. code::
|
|
69
|
+
|
|
70
|
+
pip install pybase64
|
|
71
|
+
|
|
72
|
+
Usage
|
|
73
|
+
=====
|
|
74
|
+
|
|
75
|
+
``pybase64`` uses the same API as Python base64 "modern interface" (introduced in Python 2.4) for an easy integration.
|
|
76
|
+
|
|
77
|
+
To get the fastest decoding, it is recommended to use the ``pybase64.b64decode`` and ``validate=True`` when possible.
|
|
78
|
+
|
|
79
|
+
.. code:: python
|
|
80
|
+
|
|
81
|
+
import pybase64
|
|
82
|
+
|
|
83
|
+
print(pybase64.b64encode(b'>>>foo???', altchars='_:'))
|
|
84
|
+
# b'Pj4_Zm9vPz8:'
|
|
85
|
+
print(pybase64.b64decode(b'Pj4_Zm9vPz8:', altchars='_:', validate=True))
|
|
86
|
+
# b'>>>foo???'
|
|
87
|
+
|
|
88
|
+
# Standard encoding helpers
|
|
89
|
+
print(pybase64.standard_b64encode(b'>>>foo???'))
|
|
90
|
+
# b'Pj4+Zm9vPz8/'
|
|
91
|
+
print(pybase64.standard_b64decode(b'Pj4+Zm9vPz8/'))
|
|
92
|
+
# b'>>>foo???'
|
|
93
|
+
|
|
94
|
+
# URL safe encoding helpers
|
|
95
|
+
print(pybase64.urlsafe_b64encode(b'>>>foo???'))
|
|
96
|
+
# b'Pj4-Zm9vPz8_'
|
|
97
|
+
print(pybase64.urlsafe_b64decode(b'Pj4-Zm9vPz8_'))
|
|
98
|
+
# b'>>>foo???'
|
|
99
|
+
|
|
100
|
+
.. begin cli
|
|
101
|
+
|
|
102
|
+
A command-line tool is also provided. It has encode, decode and benchmark subcommands.
|
|
103
|
+
|
|
104
|
+
.. code::
|
|
105
|
+
|
|
106
|
+
usage: pybase64 [-h] [-V] {benchmark,encode,decode} ...
|
|
107
|
+
|
|
108
|
+
pybase64 command-line tool.
|
|
109
|
+
|
|
110
|
+
positional arguments:
|
|
111
|
+
{benchmark,encode,decode}
|
|
112
|
+
tool help
|
|
113
|
+
benchmark -h for usage
|
|
114
|
+
encode -h for usage
|
|
115
|
+
decode -h for usage
|
|
116
|
+
|
|
117
|
+
optional arguments:
|
|
118
|
+
-h, --help show this help message and exit
|
|
119
|
+
-V, --version show program's version number and exit
|
|
120
|
+
|
|
121
|
+
.. end cli
|
|
122
|
+
|
|
123
|
+
Full documentation on `Read the Docs <http://pybase64.readthedocs.io/en/stable/?badge=stable>`_.
|
|
124
|
+
|
|
125
|
+
Benchmark
|
|
126
|
+
=========
|
|
127
|
+
|
|
128
|
+
.. begin benchmark
|
|
129
|
+
|
|
130
|
+
Running Python 3.7.2, Apple LLVM version 10.0.0 (clang-1000.11.45.5), Mac OS X 10.14.2 on an Intel Core i7-4870HQ @ 2.50GHz
|
|
131
|
+
|
|
132
|
+
.. code::
|
|
133
|
+
|
|
134
|
+
pybase64 0.5.0 (C extension active - AVX2)
|
|
135
|
+
bench: altchars=None, validate=False
|
|
136
|
+
pybase64._pybase64.encodebytes: 1734.776 MB/s (13,271,472 bytes -> 17,928,129 bytes)
|
|
137
|
+
pybase64._pybase64.b64encode: 4039.539 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
138
|
+
pybase64._pybase64.b64decode: 1854.423 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
139
|
+
base64.encodebytes: 78.352 MB/s (13,271,472 bytes -> 17,928,129 bytes)
|
|
140
|
+
base64.b64encode: 539.840 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
141
|
+
base64.b64decode: 287.826 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
142
|
+
bench: altchars=None, validate=True
|
|
143
|
+
pybase64._pybase64.b64encode: 4156.607 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
144
|
+
pybase64._pybase64.b64decode: 4107.997 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
145
|
+
base64.b64encode: 559.342 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
146
|
+
base64.b64decode: 143.674 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
147
|
+
bench: altchars=b'-_', validate=False
|
|
148
|
+
pybase64._pybase64.b64encode: 2786.776 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
149
|
+
pybase64._pybase64.b64decode: 1124.136 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
150
|
+
base64.b64encode: 322.427 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
151
|
+
base64.b64decode: 205.195 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
152
|
+
bench: altchars=b'-_', validate=True
|
|
153
|
+
pybase64._pybase64.b64encode: 2806.271 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
154
|
+
pybase64._pybase64.b64decode: 2740.456 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
155
|
+
base64.b64encode: 314.709 MB/s (13,271,472 bytes -> 17,695,296 bytes)
|
|
156
|
+
base64.b64decode: 121.803 MB/s (17,695,296 bytes -> 13,271,472 bytes)
|
|
157
|
+
|
|
158
|
+
.. end benchmark
|
|
159
|
+
|
|
160
|
+
.. begin changelog
|
|
161
|
+
|
|
162
|
+
Changelog
|
|
163
|
+
=========
|
|
164
|
+
1.4.2
|
|
165
|
+
-----
|
|
166
|
+
- Update base64 library (Windows ARM64 Neon support)
|
|
167
|
+
- Publish Python 3.14 wheels
|
|
168
|
+
- Publish Linux riscv64 wheels
|
|
169
|
+
- Publish Android wheels
|
|
170
|
+
- Publish iOS wheels
|
|
171
|
+
- Publish GraalPy wheels
|
|
172
|
+
|
|
173
|
+
1.4.1
|
|
174
|
+
-----
|
|
175
|
+
- Publish PyPy 3.11 wheels
|
|
176
|
+
- Publish armv7l wheels
|
|
177
|
+
|
|
178
|
+
1.4.0
|
|
179
|
+
-----
|
|
180
|
+
- Publish python 3.13 wheels
|
|
181
|
+
- Add support for free-threaded builds
|
|
182
|
+
- Add MSYS2 support for C-extension
|
|
183
|
+
- Better logging on base64 build failure when C-extension build is optional
|
|
184
|
+
- Drop python 3.6 & 3.7 support
|
|
185
|
+
|
|
186
|
+
1.3.2
|
|
187
|
+
-----
|
|
188
|
+
- Update base64 library
|
|
189
|
+
- PyPy: fix wrong outcome with non C-contiguous buffer
|
|
190
|
+
|
|
191
|
+
1.3.1
|
|
192
|
+
-----
|
|
193
|
+
- Add missing py.typed marker
|
|
194
|
+
|
|
195
|
+
1.3.0
|
|
196
|
+
-----
|
|
197
|
+
- Update base64 library
|
|
198
|
+
- Add AVX512-VBMI implementation
|
|
199
|
+
- Rework extension build to remove adherence on distutils
|
|
200
|
+
- Publish python 3.12 wheels
|
|
201
|
+
- Documentation now uses furo theme
|
|
202
|
+
|
|
203
|
+
1.2.3
|
|
204
|
+
-----
|
|
205
|
+
- Update base64 library
|
|
206
|
+
- Publish python 3.11 wheels
|
|
207
|
+
|
|
208
|
+
1.2.2
|
|
209
|
+
-----
|
|
210
|
+
- Update base64 library
|
|
211
|
+
- Fix C extension build on musl distros
|
|
212
|
+
- Publish musllinux wheels
|
|
213
|
+
|
|
214
|
+
1.2.1
|
|
215
|
+
-----
|
|
216
|
+
- Publish PyPy 3.8 (pypy38_pp73) wheels
|
|
217
|
+
|
|
218
|
+
1.2.0
|
|
219
|
+
-----
|
|
220
|
+
- Release the GIL
|
|
221
|
+
- Publish CPython 3.10 wheels
|
|
222
|
+
- Drop python 3.5 support
|
|
223
|
+
|
|
224
|
+
1.1.4
|
|
225
|
+
-----
|
|
226
|
+
- Add macOS arm64 wheel
|
|
227
|
+
|
|
228
|
+
1.1.3
|
|
229
|
+
-----
|
|
230
|
+
- GitHub Actions: fix build on tag
|
|
231
|
+
|
|
232
|
+
1.1.2
|
|
233
|
+
-----
|
|
234
|
+
- Add PyPy wheels
|
|
235
|
+
- Add aarch64, ppc64le & s390x manylinux wheels
|
|
236
|
+
|
|
237
|
+
1.1.1
|
|
238
|
+
-----
|
|
239
|
+
- Move CI from TravisCI/AppVeyor to GitHub Actions
|
|
240
|
+
- Fix publication of Linux/macOS wheels
|
|
241
|
+
|
|
242
|
+
1.1.0
|
|
243
|
+
-----
|
|
244
|
+
- Add b64encode_as_string, same as b64encode but returns a str object instead of a bytes object
|
|
245
|
+
- Add b64decode_as_bytearray, same as b64decode but returns a bytarray object instead of a bytes object
|
|
246
|
+
- Speed-Up decoding from UCS1 strings
|
|
247
|
+
|
|
248
|
+
1.0.2
|
|
249
|
+
-----
|
|
250
|
+
- Update base64 library
|
|
251
|
+
- Publish python 3.9 wheels
|
|
252
|
+
|
|
253
|
+
1.0.1
|
|
254
|
+
-----
|
|
255
|
+
- Publish python 3.8 wheels
|
|
256
|
+
|
|
257
|
+
1.0.0
|
|
258
|
+
-----
|
|
259
|
+
- Drop python 3.4 support
|
|
260
|
+
- Drop python 2.7 support
|
|
261
|
+
|
|
262
|
+
0.5.0
|
|
263
|
+
-----
|
|
264
|
+
- Publish python 3.7 wheels
|
|
265
|
+
- Drop python 3.3 support
|
|
266
|
+
|
|
267
|
+
0.4.0
|
|
268
|
+
-----
|
|
269
|
+
- Speed-up decoding when validate==False
|
|
270
|
+
|
|
271
|
+
0.3.1
|
|
272
|
+
-----
|
|
273
|
+
- Fix deployment issues
|
|
274
|
+
|
|
275
|
+
0.3.0
|
|
276
|
+
-----
|
|
277
|
+
- Add encodebytes function
|
|
278
|
+
|
|
279
|
+
0.2.1
|
|
280
|
+
-----
|
|
281
|
+
- Fixed invalid results on Windows
|
|
282
|
+
|
|
283
|
+
0.2.0
|
|
284
|
+
-----
|
|
285
|
+
- Added documentation
|
|
286
|
+
- Added subcommands to the main script:
|
|
287
|
+
|
|
288
|
+
* help
|
|
289
|
+
* version
|
|
290
|
+
* encode
|
|
291
|
+
* decode
|
|
292
|
+
* benchmark
|
|
293
|
+
|
|
294
|
+
0.1.2
|
|
295
|
+
-----
|
|
296
|
+
- Updated base64 native library
|
|
297
|
+
|
|
298
|
+
0.1.1
|
|
299
|
+
-----
|
|
300
|
+
- Fixed deployment issues
|
|
301
|
+
|
|
302
|
+
0.1.0
|
|
303
|
+
-----
|
|
304
|
+
- First public release
|
|
305
|
+
|
|
306
|
+
.. end changelog
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
pybase64/__init__.py,sha256=wb_YG09m0-rC6lPmDKF62XsEcVhGkCxcPw2GZyxE9L4,3230
|
|
2
|
+
pybase64/__main__.py,sha256=djZqQ6QNmgIAjvYHQa-uIApZhxyUZj2UzvDeQjfLn0w,8530
|
|
3
|
+
pybase64/_fallback.py,sha256=L-i5KnRtLU2PfBbKIL2hNiHmNrWs1LeWYh3xGD8mriM,5800
|
|
4
|
+
pybase64/_license.py,sha256=Lu3v1O3buEcMPgKC5f4r523lGvNGgoTXhHnHh0Ys1kw,3116
|
|
5
|
+
pybase64/_license.pyi,sha256=aTpwZqUJh82NsyBwHhQo_cJRZsBYSARCKxGdtb1QYPk,14
|
|
6
|
+
pybase64/_pybase64.cpython-313-aarch64-linux-android.so,sha256=W7dRgH0KrQLx3SMGigFag79Asc3b1LeNudS56UB8vSc,48016
|
|
7
|
+
pybase64/_pybase64.pyi,sha256=wxk6eoWmafyE9NOVr2j9T0E2w2lSC-ImIL5E-HP1XcE,679
|
|
8
|
+
pybase64/_typing.py,sha256=QvyxFSzktrAAOT2ohlB5ah1WDbqL6bnZDRvgemDZY1k,709
|
|
9
|
+
pybase64/_version.py,sha256=_VSFxJfXwKW9isWsQYEeKF59rytvn_LO7yJ2uuV-LL0,55
|
|
10
|
+
pybase64/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
11
|
+
pybase64-1.4.2.dist-info/licenses/LICENSE,sha256=XlI7VMFYHUT0WL_dLNOUTWIrsaMqpB8Hc-5No5D7RbQ,1326
|
|
12
|
+
pybase64-1.4.2.dist-info/METADATA,sha256=JJqLdcfA01uCrnwagf4Jn44a_WeJcs9fTZaoL_IjXa0,8663
|
|
13
|
+
pybase64-1.4.2.dist-info/WHEEL,sha256=5I58AbR9O_ArnZQueeIBJrrQjT_lZqa3wHwMOp-EJ_E,112
|
|
14
|
+
pybase64-1.4.2.dist-info/entry_points.txt,sha256=qLhLeuPRnj6ju76SqeVYOuxavmDKx9ZWjXHLltpLa5o,52
|
|
15
|
+
pybase64-1.4.2.dist-info/top_level.txt,sha256=Tm3tmGpMnLWAvjrxORS2E5I6LARaLepOEUjGaTmFuZg,9
|
|
16
|
+
pybase64-1.4.2.dist-info/RECORD,,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
BSD 2-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2017-2022, Matthieu Darbois
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
17
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
18
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
19
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
20
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
21
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
22
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
23
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
24
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
25
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pybase64
|