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

68 statements  

« prev     ^ index     » next       coverage.py v7.2.2, created at 2023-03-26 07:30 +0000

1# 

2# This file is part of pyasn1 software. 

3# 

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

5# License: http://snmplabs.com/pyasn1/license.html 

6# 

7import sys 

8 

9try: 

10 import platform 

11 

12 implementation = platform.python_implementation() 

13 

14except (ImportError, AttributeError): 

15 implementation = 'CPython' 

16 

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

18 

19if sys.version_info[0:2] < (3, 2) or implementation != 'CPython': 

20 from binascii import a2b_hex, b2a_hex 

21 

22 if sys.version_info[0] > 2: 

23 long = int 

24 

25 def from_bytes(octets, signed=False): 

26 if not octets: 

27 return 0 

28 

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

30 

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

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

33 

34 return value 

35 

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

37 if value < 0: 

38 if signed: 

39 bits = bitLength(value) 

40 

41 # two's complement form 

42 maxValue = 1 << bits 

43 valueToEncode = (value + maxValue) % maxValue 

44 

45 else: 

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

47 elif value == 0 and length == 0: 

48 return null 

49 else: 

50 bits = 0 

51 valueToEncode = value 

52 

53 hexValue = hex(valueToEncode)[2:] 

54 if hexValue.endswith('L'): 

55 hexValue = hexValue[:-1] 

56 

57 if len(hexValue) & 1: 

58 hexValue = '0' + hexValue 

59 

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

61 if value != valueToEncode or length: 

62 hexLength = len(hexValue) * 4 

63 

64 padLength = max(length, bits) 

65 

66 if padLength > hexLength: 

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

68 elif length and hexLength - length > 7: 

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

70 

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

72 

73 if signed: 

74 if firstOctet & 0x80: 

75 if value >= 0: 

76 hexValue = '00' + hexValue 

77 elif value < 0: 

78 hexValue = 'ff' + hexValue 

79 

80 octets_value = a2b_hex(hexValue) 

81 

82 return octets_value 

83 

84 def bitLength(number): 

85 # bits in unsigned number 

86 hexValue = hex(abs(number)) 

87 bits = len(hexValue) - 2 

88 if hexValue.endswith('L'): 

89 bits -= 1 

90 if bits & 1: 

91 bits += 1 

92 bits *= 4 

93 # TODO: strip lhs zeros 

94 return bits 

95 

96else: 

97 

98 def from_bytes(octets, signed=False): 

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

100 

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

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

103 

104 if signed and length % 8 == 0: 

105 length += 1 

106 

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

108 

109 def bitLength(number): 

110 return int(number).bit_length()