I want to change a registry key value via Python. The value type will be REG_DWORD which means hexadecimal including 0x000 in integer format. I am having trouble converting a string with a number to its hexadecimal format in integer.
Since I am looping through a number of registry keys, my code to change a certain key is as follows:
for i in range(len(checking_names)): #loop through names to check
if checking_names(i) !== should_values(i): #no match
with winreg.CreateKeyEx(key, subkey_path, 0, winreg.KEY_ALL_ACCESS) as subkey:
winreg.DeleteValue(subkey, names_data[i]) #have to delete name in order to overwrite
winreg.SetValueEx(subkey, names_data[i], 0, winreg.REG_DWORD, new_hex_value) #overwrite name value with correct value from predefined list
My values_data list is comprised of predefined variables as strings. One of the entries is a string '9600'. In my above code, values_data[i] should be 9600 in hexadecimal format: 0x00002580. For this conversion I do the following:
dec_to_hex_str = format(int(values_data[i]),'x') #string decimal to string hexadecimal conversion
zeros_pre_x = '0x' #0x for format 0xffffffff
zeros_to_add = 8 - len(dec_to_hex_str) #count number of leading 0s to add
mid_zeros_list = []
for j in range(zeros_to_add):
mid_zeros_list.append(0) #add a leading 0
mid_zeros = ''.join(mid_zeros_list) #convert list to string
new_hex_value = int(zeros_pre_hex + mid_zeros + dec_to_hex_str)
When I run this code, my Python shell is unresponsive, and there is no change in the Windows registry for the subkey value. The problem seems to be, that winreg.SetValueEx .... winreg.REG_DWORD only understands integer format but my new_hex_value is not being properly converted from string to integer.
Any help would be appreciated!
Your problem lies in the line
new_hex_value = int(zeros_pre_hex + mid_zeros + dec_to_hex_str)
You are converting the number to a hex string, then converting it into an integer. Not only is this an invalid argument to int(), but even if it were correct, you would just be converting it back to an integer (there is no such thing as a hex integer in Python). So your line should read:
new_hex_value = zeros_pre_hex + mid_zeros + dec_to_hex_str
Then simply write this as a REG_SZ because you want a hex string, not an integer. There is no "hex integer" in the registry either.
Related
I have a table Widget and user give a number in table, so when I get this value I want to convert 32 bit hex value.
For example user enter number 10, I need to convert this number
Firstly 0x000A (it need to be hex)
And split like this myList = [0x0,0x0,0x0,0xA]
I tried with below command
myNum = 10
value = '0x{0:04X}'.format(myNum)
print(value)
print(list(struct.pack('<H',value)))
I get struct.error: required argument is not an integer
'0x{0:04X}'.format(myNum) value return string so I couldnt split this value correctly.
I expect this value [0x0,0x0,0x0,0xA]
How can I do that ?
You cannot do a strut.pack on a string. It takes integers (as the error describes) and returns a byte string, which you can turn into a list.
import struct
myNum = 10
myHex = '0x{0:04X}'.format(myNum)
print(myHex)
mylist = list(struct.pack('>I',myNum))
print(mylist)
print(list(map(hex, mylist)))
The last line prints them as hex, but they are not integers, they are strings. And you are trying to use little endian in your code, but the expected output is in Big.
I want to convert my int number into an hex one specifying the number of characters in my final hex representation.
This is my simple code that takes an input an converts it into hex:
my_number = int(1234)
hex_version = hex(my_number)
This code returns a string equal to 0x4d2.
However I would like my output to contain 16 characters, so basically it should be 0x00000000000004d2.
Is there a way to specify the number of output character to the hex() operator? So that it pads for the needed amount of 0.
From Python's Format Specification Mini-Language:
n = int(1234)
h = format(n, '#018x')
The above will generate the required string. The magic number 18 is obtained as follows: 16 for the width you need + 2 for '0' (zero) and 'x' (for the hex descriptor string prefix).
Similar to this other question on decoding a hex string, I have some code in a Python 2.7 script which has worked for years. I'm now trying to convert that script to Python 3.
OK, I apologize for not posting a complete question initially. I hope this clarifies the situation.
The issue is that I'm trying to convert an older Python 2.7 script to Python 3.8. For the most part the conversion has gone ok, but I am having issues converting the following code:
# get Register Stings
RegString = ""
for i in range(length):
if regs[start+i]!=0:
RegString = RegString + str(format(regs[start+i],'x').decode('hex'))
Here are some suppodrting data:
regs[start+0] = 20341
regs[start+1] = 29762
I think that my Python 2.7 code is converting these to HEX as "4f75" and "7442", respectively. And then to the characters "Ou" and "tB", respectively.
In Python 3 I get this error:
'str' object has no attribute 'decode'
My goal is to modify my Python 3 code so that the script will generate the same results.
str(format(regs[start+i],'x').decode('hex')) is a very verbose and round-about way of turning the non-zero integer values in regs[start:start + length] into individual characters of a bytestring (str in Python 2 should really be seen as a sequence of bytes). It first converts an integer value into a hexadecimal representation (a string), decodes that hexadecimal string to a (series) of string characters, then calls str() on the result (redundantly, the value is already a string). Assuming that the values in regs are integers in the range 0-255 (or even 0-127), in Python 2 this should really have been using the chr() function.
If you want to preserve the loop use chr() (to get a str string value) or if you need a binary value, use bytes([...]). So:
RegString = ""
for codepoint in regs[start:start + length]:
RegString += chr(codepoint)
or
RegString = b""
for codepoint in regs[start:start + length]:
RegString += bytes([codepoint])
Since this is actually converting a sequence of integers, you can just pass the whole lot to bytes() and filter out the zeros as you go:
# only take non-zero values
RegString = bytes(b for b in regs[start:start + length] if b)
or remove the nulls afterwards:
RegString = bytes(regs[start:start + length]).replace(b"\x00", b"")
If that's still supposed to be a string and not a bytes value, you can then decode it, with whatever encoding is appropriate (ASCII if the integers are in the range 0-127, or a more specific codec otherwise, in Python 2 this code produced a bytestring so look for other hints in the code as to what encoding they might have been using).
I am converting a string into integer using int function and it is working fine but i want to keep save zero digit that are at the start of the string.
string_value = '0123'
print(int(string_value))
result is 123
How can i format output 0123 as in integer type value not in string.
You can't, but if you want to put 0's (zero padding) at the beginning of your number, this is the way to do it.
"{:04}".format(123)
# '0123'
"{:05}".format(123)
# '00123'
Like every one said you can try above answers or the following :
string_value = '0123'
int_no = int(string_value)
print("%04d" % int_no)
print(string_value.zfill(4))
Both will give same answer
Impossible, you cannot get an integer value of 0123.
You should change your mind, you do not actually need 0123 in integer, but you need to keep zero when displaying it. So the question should change to how to format output.
Trying to get a double-precision floating point score from a UTF-8 encoded string object in Python. The idea is to grab the first 8 bytes of the string and create a float, so that the strings, ordered by their score, would be ordered lexicographically according to their first 8 bytes (or possibly their first 63 bits, after forcing them all to be positive to avoid sign errors).
For example:
get_score(u'aaaaaaa') < get_score(u'aaaaaaab') < get_score(u'zzzzzzzz')
I have tried to compute the score in an integer using bit-shift-left and XOR, but I am not sure of how to translate that into a float value. I am also not sure if there is a better way to do this.
How should the score for a string be computed so the condition I specified before is met?
Edit: The string object is UTF-8 encoded (as per #Bakuriu's commment).
float won't give you 64 bits of precision. Use integers instead.
def get_score(s):
return struct.unpack('>Q', (u'\0\0\0\0\0\0\0\0' + s[:8])[-8:])[0]
In Python 3:
def get_score(s):
return struct.unpack('>Q', ('\0\0\0\0\0\0\0\0' + s[:8])[-8:].encode('ascii', 'error'))[0]
EDIT:
For floats, with 6 characters:
def get_score(s):
return struct.unpack('>d', (u'\0\1' + (u'\0\0\0\0\0\0\0\0' + s[:6])[-6:]).encode('ascii', 'error'))[0]
You will need to setup the entire alphabet and do the conversion by hand, since conversions to base > 36 are not built in, in order to do that you only need to define the complete alphabet to use. If it was an ascii string for instance you would create a conversion to a long in base 256 from the input string using all the ascii table as an alphabet.
You have an example of the full functions to do it here: string to base 62 number
Also you don't need to worry about negative-positive numbers when doing this, since the encoding of the string with the first character in the alphabet will yield the minimum possible number in the representation, which is the negative value with the highest absolute value, in your case -2**63 which is the correct value and allows you to use < > against it.
Hope it helps!