diff options
author | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-09-16 12:05:47 +0200 |
---|---|---|
committer | Sybren A. Stüvel <sybren@stuvel.eu> | 2018-09-16 12:05:47 +0200 |
commit | ae61397ce7a57969b14eb900f30b76e666170e62 (patch) | |
tree | 0d890e4af3704d793f37646906ef867d4746b861 | |
parent | ad510185b54412f390f2ffcb2f8362326a1b0885 (diff) | |
download | rsa-git-ae61397ce7a57969b14eb900f30b76e666170e62.tar.gz |
Moved `get_word_alignment()` from `_compat.py` to `machine_size.py`
In preparation of removal of Python 2.7 support, I only want to have
compatibility code for Python 2.7 in `_compat.py`, and not other kinds
of 'compatibility'.
-rw-r--r-- | rsa/machine_size.py | 74 | ||||
-rw-r--r-- | rsa/transform.py | 6 |
2 files changed, 77 insertions, 3 deletions
diff --git a/rsa/machine_size.py b/rsa/machine_size.py new file mode 100644 index 0000000..2a871b8 --- /dev/null +++ b/rsa/machine_size.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# +# Copyright 2011 Sybren A. Stüvel <sybren@stuvel.eu> +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Detection of 32-bit and 64-bit machines and byte alignment.""" + +import sys + +MAX_INT = sys.maxsize +MAX_INT64 = (1 << 63) - 1 +MAX_INT32 = (1 << 31) - 1 +MAX_INT16 = (1 << 15) - 1 + +# Determine the word size of the processor. +if MAX_INT == MAX_INT64: + # 64-bit processor. + MACHINE_WORD_SIZE = 64 +elif MAX_INT == MAX_INT32: + # 32-bit processor. + MACHINE_WORD_SIZE = 32 +else: + # Else we just assume 64-bit processor keeping up with modern times. + MACHINE_WORD_SIZE = 64 + + +def get_word_alignment(num, force_arch=64, + _machine_word_size=MACHINE_WORD_SIZE): + """ + Returns alignment details for the given number based on the platform + Python is running on. + + :param num: + Unsigned integral number. + :param force_arch: + If you don't want to use 64-bit unsigned chunks, set this to + anything other than 64. 32-bit chunks will be preferred then. + Default 64 will be used when on a 64-bit machine. + :param _machine_word_size: + (Internal) The machine word size used for alignment. + :returns: + 4-tuple:: + + (word_bits, word_bytes, + max_uint, packing_format_type) + """ + max_uint64 = 0xffffffffffffffff + max_uint32 = 0xffffffff + max_uint16 = 0xffff + max_uint8 = 0xff + + if force_arch == 64 and _machine_word_size >= 64 and num > max_uint32: + # 64-bit unsigned integer. + return 64, 8, max_uint64, "Q" + elif num > max_uint16: + # 32-bit unsigned integer + return 32, 4, max_uint32, "L" + elif num > max_uint8: + # 16-bit unsigned integer. + return 16, 2, max_uint16, "H" + else: + # 8-bit unsigned integer. + return 8, 1, max_uint8, "B" diff --git a/rsa/transform.py b/rsa/transform.py index acf044d..628d0af 100644 --- a/rsa/transform.py +++ b/rsa/transform.py @@ -24,8 +24,8 @@ from __future__ import absolute_import import binascii from struct import pack -from rsa import common -from rsa._compat import byte, is_integer, get_word_alignment +from rsa._compat import byte, is_integer +from rsa import common, machine_size def bytes2int(raw_bytes): @@ -181,7 +181,7 @@ def int2bytes(number, fill_size=None, chunk_size=None, overflow=False): # Pack the integer one machine word at a time into bytes. num = number - word_bits, _, max_uint, pack_type = get_word_alignment(num) + word_bits, _, max_uint, pack_type = machine_size.get_word_alignment(num) pack_format = ">%s" % pack_type while num > 0: raw_bytes = pack(pack_format, num & max_uint) + raw_bytes |