Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/pyasn1/compat/integer.py: 14%

63 statements  

« prev     ^ index     » next       coverage.py v7.3.2, created at 2023-12-08 06:40 +0000

1# 

2# This file is part of pyasn1 software. 

3# 

4# Copyright (c) 2005-2020, Ilya Etingof <etingof@gmail.com> 

5# License: https://pyasn1.readthedocs.io/en/latest/license.html 

6# 

7import sys 

8import platform 

9 

10from pyasn1.compat.octets import oct2int, null, ensureString 

11 

12 

13implementation = platform.python_implementation() 

14 

15if sys.version_info[0] < 3: 

16 from binascii import a2b_hex, b2a_hex 

17 

18 def from_bytes(octets, signed=False): 

19 if not octets: 

20 return 0 

21 

22 value = long(b2a_hex(ensureString(octets)), 16) 

23 

24 if signed and oct2int(octets[0]) & 0x80: 

25 return value - (1 << len(octets) * 8) 

26 

27 return value 

28 

29 def to_bytes(value, signed=False, length=0): 

30 if value < 0: 

31 if signed: 

32 bits = bitLength(value) 

33 

34 # two's complement form 

35 maxValue = 1 << bits 

36 valueToEncode = (value + maxValue) % maxValue 

37 

38 else: 

39 raise OverflowError('can\'t convert negative int to unsigned') 

40 elif value == 0 and length == 0: 

41 return null 

42 else: 

43 bits = 0 

44 valueToEncode = value 

45 

46 hexValue = hex(valueToEncode)[2:] 

47 if hexValue.endswith('L'): 

48 hexValue = hexValue[:-1] 

49 

50 if len(hexValue) & 1: 

51 hexValue = '0' + hexValue 

52 

53 # padding may be needed for two's complement encoding 

54 if value != valueToEncode or length: 

55 hexLength = len(hexValue) * 4 

56 

57 padLength = max(length, bits) 

58 

59 if padLength > hexLength: 

60 hexValue = '00' * ((padLength - hexLength - 1) // 8 + 1) + hexValue 

61 elif length and hexLength - length > 7: 

62 raise OverflowError('int too big to convert') 

63 

64 firstOctet = int(hexValue[:2], 16) 

65 

66 if signed: 

67 if firstOctet & 0x80: 

68 if value >= 0: 

69 hexValue = '00' + hexValue 

70 elif value < 0: 

71 hexValue = 'ff' + hexValue 

72 

73 octets_value = a2b_hex(hexValue) 

74 

75 return octets_value 

76 

77 def bitLength(number): 

78 # bits in unsigned number 

79 hexValue = hex(abs(number)) 

80 bits = len(hexValue) - 2 

81 if hexValue.endswith('L'): 

82 bits -= 1 

83 if bits & 1: 

84 bits += 1 

85 bits *= 4 

86 # TODO: strip lhs zeros 

87 return bits 

88 

89else: 

90 

91 def from_bytes(octets, signed=False): 

92 return int.from_bytes(bytes(octets), 'big', signed=signed) 

93 

94 def to_bytes(value, signed=False, length=0): 

95 length = max(value.bit_length(), length) 

96 

97 if signed and length % 8 == 0: 

98 length += 1 

99 

100 return value.to_bytes(length // 8 + (length % 8 and 1 or 0), 'big', signed=signed) 

101 

102 def bitLength(number): 

103 return int(number).bit_length()