You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					111 lines
				
				2.9 KiB
			
		
		
			
		
	
	
					111 lines
				
				2.9 KiB
			| 
								 
											3 years ago
										 
									 | 
							
								#
							 | 
						||
| 
								 | 
							
								# This file is part of pyasn1 software.
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								# Copyright (c) 2005-2019, Ilya Etingof <etingof@gmail.com>
							 | 
						||
| 
								 | 
							
								# License: http://snmplabs.com/pyasn1/license.html
							 | 
						||
| 
								 | 
							
								#
							 | 
						||
| 
								 | 
							
								import sys
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								try:
							 | 
						||
| 
								 | 
							
								    import platform
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    implementation = platform.python_implementation()
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								except (ImportError, AttributeError):
							 | 
						||
| 
								 | 
							
								    implementation = 'CPython'
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								from pyasn1.compat.octets import oct2int, null, ensureString
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								if sys.version_info[0:2] < (3, 2) or implementation != 'CPython':
							 | 
						||
| 
								 | 
							
								    from binascii import a2b_hex, b2a_hex
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    if sys.version_info[0] > 2:
							 | 
						||
| 
								 | 
							
								        long = int
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def from_bytes(octets, signed=False):
							 | 
						||
| 
								 | 
							
								        if not octets:
							 | 
						||
| 
								 | 
							
								            return 0
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        value = long(b2a_hex(ensureString(octets)), 16)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if signed and oct2int(octets[0]) & 0x80:
							 | 
						||
| 
								 | 
							
								            return value - (1 << len(octets) * 8)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def to_bytes(value, signed=False, length=0):
							 | 
						||
| 
								 | 
							
								        if value < 0:
							 | 
						||
| 
								 | 
							
								            if signed:
							 | 
						||
| 
								 | 
							
								                bits = bitLength(value)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								                # two's complement form
							 | 
						||
| 
								 | 
							
								                maxValue = 1 << bits
							 | 
						||
| 
								 | 
							
								                valueToEncode = (value + maxValue) % maxValue
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            else:
							 | 
						||
| 
								 | 
							
								                raise OverflowError('can\'t convert negative int to unsigned')
							 | 
						||
| 
								 | 
							
								        elif value == 0 and length == 0:
							 | 
						||
| 
								 | 
							
								            return null
							 | 
						||
| 
								 | 
							
								        else:
							 | 
						||
| 
								 | 
							
								            bits = 0
							 | 
						||
| 
								 | 
							
								            valueToEncode = value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        hexValue = hex(valueToEncode)[2:]
							 | 
						||
| 
								 | 
							
								        if hexValue.endswith('L'):
							 | 
						||
| 
								 | 
							
								            hexValue = hexValue[:-1]
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if len(hexValue) & 1:
							 | 
						||
| 
								 | 
							
								            hexValue = '0' + hexValue
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        # padding may be needed for two's complement encoding
							 | 
						||
| 
								 | 
							
								        if value != valueToEncode or length:
							 | 
						||
| 
								 | 
							
								            hexLength = len(hexValue) * 4
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            padLength = max(length, bits)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								            if padLength > hexLength:
							 | 
						||
| 
								 | 
							
								                hexValue = '00' * ((padLength - hexLength - 1) // 8 + 1) + hexValue
							 | 
						||
| 
								 | 
							
								            elif length and hexLength - length > 7:
							 | 
						||
| 
								 | 
							
								                raise OverflowError('int too big to convert')
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        firstOctet = int(hexValue[:2], 16)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if signed:
							 | 
						||
| 
								 | 
							
								            if firstOctet & 0x80:
							 | 
						||
| 
								 | 
							
								                if value >= 0:
							 | 
						||
| 
								 | 
							
								                    hexValue = '00' + hexValue
							 | 
						||
| 
								 | 
							
								            elif value < 0:
							 | 
						||
| 
								 | 
							
								                hexValue = 'ff' + hexValue
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        octets_value = a2b_hex(hexValue)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return octets_value
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def bitLength(number):
							 | 
						||
| 
								 | 
							
								        # bits in unsigned number
							 | 
						||
| 
								 | 
							
								        hexValue = hex(abs(number))
							 | 
						||
| 
								 | 
							
								        bits = len(hexValue) - 2
							 | 
						||
| 
								 | 
							
								        if hexValue.endswith('L'):
							 | 
						||
| 
								 | 
							
								            bits -= 1
							 | 
						||
| 
								 | 
							
								        if bits & 1:
							 | 
						||
| 
								 | 
							
								            bits += 1
							 | 
						||
| 
								 | 
							
								        bits *= 4
							 | 
						||
| 
								 | 
							
								        # TODO: strip lhs zeros
							 | 
						||
| 
								 | 
							
								        return bits
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								else:
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def from_bytes(octets, signed=False):
							 | 
						||
| 
								 | 
							
								        return int.from_bytes(bytes(octets), 'big', signed=signed)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def to_bytes(value, signed=False, length=0):
							 | 
						||
| 
								 | 
							
								        length = max(value.bit_length(), length)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        if signed and length % 8 == 0:
							 | 
						||
| 
								 | 
							
								            length += 1
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								        return value.to_bytes(length // 8 + (length % 8 and 1 or 0), 'big', signed=signed)
							 | 
						||
| 
								 | 
							
								
							 | 
						||
| 
								 | 
							
								    def bitLength(number):
							 | 
						||
| 
								 | 
							
								        return int(number).bit_length()
							 |