How to convert string to hexadecimal integer in Python? - python

hi I get user argv from command line as follows: '0x000aff00'
and I want python to treat it as hex directly...
str = sys.argv[1]
how is it possible? thanks!

Try: i = int(sys.argv[1], 16)

try:
i = int(sys.argv[1], 16)
except Exception,e:
print e
else:
# carry on

Related

How to pass char* to Python

I need to pass two Python strings, representing an input file and an output file, to a C function named decrypt_file.
If I hardcode the string (for example, 'Test.OUT'), then it works. I don't know how to use a variable string. The C function returns a string with wrong characters.
int decrypt_file(char *inputfile, char *outputfile);
try:
file_name = bytes("example.txt", encoding='utf8')
p_file_name = ctypes.create_string_buffer(file_name, len(file_name))
so = "/home/hello/lib.so"
sodium = ctypes.CDLL(so)
sodium.strfry(p_file_name)
sodium.decrypt_file.argtypes = [ctypes.c_char_p, ctypes.c_char_p]
sodium.decrypt_file(p_file_name, ctypes.c_char_p(b"Test.OUT"))
except Exception as e:
print(e)
return -> input file: mlxta.txeep
I use Linux and Pycharm terminal. Thanks for any tips.
ctypes was wrong. I don't know if this is the right way but it works.
filename = b"helloworld.txt"
so = "/home/lib.so"
sodium = ctypes.CDLL(so)
sodium.decrypt_file.argtypes = [ctypes.POINTER(ctypes.c_char), ctypes.c_char_p]
sodium.decrypt_file(filename, ctypes.c_char_p(b"Test.OUT"))

Manipulating strings in python with f strings: handling long strings

How do i handle long strings while printing with f-Strings.
I am only interested in the first -and last n of the string (especially in this case the extension of a file). The middle part should be replaced with 3 dots.
As an example:
instead of:
ThisIsMyFilexyz123456s556s54s6afsaf1dshshsb8bbs6s7890.py
ThisIsMyFilexyz12345asaggsvrgahhgbargrarbrvs7890.pdf
ThisIsMyFilexyz12345asa46189sgvs7890.gif
ThisIsMyFilexyz1sgsgbs6rahhgbargrarbrvs7890.jpg
i want this:
ThisIsMyFilexy...123.py
ThisIsMyFilexy...456.pdf
ThisIsMyFilexy...789.xml
ThisIsMyFilexy...001.gif
ThisIsMyFilexy...002.py
ThisIsMyFilexy...003.py
import os, arrow
dirname = input("Enter a directory name: ")
def last_modified(filename):
statinfo = os.stat(filename)
timestamp = statinfo.st_mtime
utc = arrow.get(timestamp)
local = utc.to('Europe/Berlin')
modified_time = local.format('DD MMMM YYYY HH:mm:ss')
return modified_time
last_time_modified = { filename : last_modified(os.path.join(dirname, filename))
for filename in os.listdir(dirname)
if os.path.isfile(os.path.join(dirname, filename))}
# **here comes the printing part**
for key, value in last_time_modified.items():
print(f'{key:<35} {value:>35}')
A combination of both, #Prem Anand & #Vishesh Mangla did it for me. Here is what i got:
def trunc(arg):
if len(arg) > 35:
return arg[:25]+"..."+arg[-10:]
else:
return arg
for key, value in last_time_modified.items():
line_new = '{:<38} {:>35}'.format(trunc(key), str(value))
print(line_new)
Thank you guys!
Define a new function that can truncate the long strings and return it in whatever format you like and use that function in the f-string
>>> def trunc(s, left=14, right=6, seperator='...'):
... return s[:left]+seperator+s[-right:]
...
>>>
>>> for key in lines:
... print(f'{trunc(key)}')
...
ThisIsMyFilexy...890.py
ThisIsMyFilexy...90.pdf
ThisIsMyFilexy...90.gif
ThisIsMyFilexy...90.jpg

unpack requires a string argument of length 24

I am not sure what I am doing wrong here but I am trying to open a file, trace1.flow, read the header information then throw the source IP and destination IP into dictionaries. This is done in Python running on a Fedora VM. I am getting the following error:
(secs, nsecs, booted, exporter, mySourceIP, myDestinationIP) = struct.unpack('IIIIII',myBuf)
struct.error: unpack requires a string argument of length 24
Here is my code:
import struct
import socket
#Dictionaries
uniqSource = {}
uniqDestination = {}
def int2quad(i):
z = struct.pack('!I', i)
return socket.inet_ntoa(z)
myFile = open('trace1.flow')
myBuf = myFile.read(8)
(magic, endian, version, headerLen) = struct.unpack('HBBI', myBuf)
print "Magic: ", hex(magic), "Endian: ", endian, "Version: ", version, "Header Length: ", headerLen
myFile.read(headerLen - 8)
try:
while(True):
myBuf = myFile.read(24)
(secs, nsecs, booted, exporter, mySourceIP, myDestinationIP) = struct.unpack('IIIIII',myBuf)
mySourceIP = int2quad(mySourceIP)
myDestinationIP = int2quad(myDestinationIP)
if mySourceIP not in uniqSource:
uniqSource[mySourceIP] = 1
else:
uniqSource[mySourceIP] += 1
if myDestinationIP not in uniqDestination:
uniqDestination[myDestinationIP] = 1
else:
uniqDestination[myDestinationIP] += 1
myFile.read(40)
except EOFError:
print "END OF FILE"
You seem to assume that file.read will raise EOFError on end of file, but this error is only raised by input() and raw_input(). file.read will simply return a string that's shorter than requested (possibly empty).
So you need to check the length after reading:
myBuf = myFile.read(24)
if len(myBuf) < 24:
break
Perhaps your have reached end-of-file. Check the length of myBuf:
len(myBuf)
It's probably less than 24 chars long. Also you don't need those extra parenthesis, and try to specify duplicated types using 'nI' like this:
secs, nsecs, booted, exporter, mySourceIP, myDestinationIP = struct.unpack('6I',myBuf)

How to encode text to base64 in python

I am trying to encode a text string to base64.
i tried doing this :
name = "your name"
print('encoding %s in base64 yields = %s\n'%(name,name.encode('base64','strict')))
But this gives me the following error:
LookupError: 'base64' is not a text encoding; use codecs.encode() to handle arbitrary codecs
How do I go about doing this ? ( using Python 3.4)
Remember to import base64 and that b64encode takes bytes as an argument.
import base64
b = base64.b64encode(bytes('your string', 'utf-8')) # bytes
base64_str = b.decode('utf-8') # convert bytes to string
It turns out that this is important enough to get it's own module...
import base64
base64.b64encode(b'your name') # b'eW91ciBuYW1l'
base64.b64encode('your name'.encode('ascii')) # b'eW91ciBuYW1l'
For py3, base64 encode and decode string:
import base64
def b64e(s):
return base64.b64encode(s.encode()).decode()
def b64d(s):
return base64.b64decode(s).decode()
1) This works without imports in Python 2:
>>>
>>> 'Some text'.encode('base64')
'U29tZSB0ZXh0\n'
>>>
>>> 'U29tZSB0ZXh0\n'.decode('base64')
'Some text'
>>>
>>> 'U29tZSB0ZXh0'.decode('base64')
'Some text'
>>>
(although this doesn't work in Python3 )
2) In Python 3 you'd have to import base64 and do base64.b64decode('...')
- will work in Python 2 too.
To compatibility with both py2 and py3
import six
import base64
def b64encode(source):
if six.PY3:
source = source.encode('utf-8')
content = base64.b64encode(source).decode('utf-8')
It looks it's essential to call decode() function to make use of actual string data even after calling base64.b64decode over base64 encoded string. Because never forget it always return bytes literals.
import base64
conv_bytes = bytes('your string', 'utf-8')
print(conv_bytes) # b'your string'
encoded_str = base64.b64encode(conv_bytes)
print(encoded_str) # b'eW91ciBzdHJpbmc='
print(base64.b64decode(encoded_str)) # b'your string'
print(base64.b64decode(encoded_str).decode()) # your string
Whilst you can of course use the base64 module, you can also to use the codecs module (referred to in your error message) for binary encodings (meaning non-standard & non-text encodings).
For example:
import codecs
my_bytes = b"Hello World!"
codecs.encode(my_bytes, "base64")
codecs.encode(my_bytes, "hex")
codecs.encode(my_bytes, "zip")
codecs.encode(my_bytes, "bz2")
This can come in useful for large data as you can chain them to get compressed and json-serializable values:
my_large_bytes = my_bytes * 10000
codecs.decode(
codecs.encode(
codecs.encode(
my_large_bytes,
"zip"
),
"base64"),
"utf8"
)
Refs:
https://docs.python.org/3/library/codecs.html#binary-transforms
https://docs.python.org/3/library/codecs.html#standard-encodings
https://docs.python.org/3/library/codecs.html#text-encodings
Use the below code:
import base64
#Taking input through the terminal.
welcomeInput= raw_input("Enter 1 to convert String to Base64, 2 to convert Base64 to String: ")
if(int(welcomeInput)==1 or int(welcomeInput)==2):
#Code to Convert String to Base 64.
if int(welcomeInput)==1:
inputString= raw_input("Enter the String to be converted to Base64:")
base64Value = base64.b64encode(inputString.encode())
print "Base64 Value = " + base64Value
#Code to Convert Base 64 to String.
elif int(welcomeInput)==2:
inputString= raw_input("Enter the Base64 value to be converted to String:")
stringValue = base64.b64decode(inputString).decode('utf-8')
print "Base64 Value = " + stringValue
else:
print "Please enter a valid value."
Base64 encoding is a process of converting binary data to an ASCII
string format by converting that binary data into a 6-bit character
representation. The Base64 method of encoding is used when binary
data, such as images or video, is transmitted over systems that are
designed to transmit data in a plain-text (ASCII) format.
Follow this link for further details about understanding and working of base64 encoding.
For those who want to implement base64 encoding from scratch for the sake of understanding, here's the code that encodes the string to base64.
encoder.py
#!/usr/bin/env python3.10
class Base64Encoder:
#base64Encoding maps integer to the encoded text since its a list here the index act as the key
base64Encoding:list = None
#data must be type of str or bytes
def encode(data)->str:
#data = data.encode("UTF-8")
if not isinstance(data, str) and not isinstance(data, bytes):
raise AttributeError(f"Expected {type('')} or {type(b'')} but found {type(data)}")
if isinstance(data, str):
data = data.encode("ascii")
if Base64Encoder.base64Encoding == None:
#construction base64Encoding
Base64Encoder.base64Encoding = list()
#mapping A-Z
for key in range(0, 26):
Base64Encoder.base64Encoding.append(chr(key + 65))
#mapping a-z
for key in range(0, 26):
Base64Encoder.base64Encoding.append(chr(key + 97))
#mapping 0-9
for key in range(0, 10):
Base64Encoder.base64Encoding.append(chr(key + 48))
#mapping +
Base64Encoder.base64Encoding.append('+')
#mapping /
Base64Encoder.base64Encoding.append('/')
if len(data) == 0:
return ""
length=len(data)
bytes_to_append = -(length%3)+(3 if length%3 != 0 else 0)
#print(f"{bytes_to_append=}")
binary_list = []
for s in data:
ascii_value = s
binary = f"{ascii_value:08b}"
#binary = bin(ascii_value)[2:]
#print(s, binary, type(binary))
for bit in binary:
binary_list.append(bit)
length=len(binary_list)
bits_to_append = -(length%6) + (6 if length%6 != 0 else 0)
binary_list.extend([0]*bits_to_append)
#print(f"{binary_list=}")
base64 = []
value = 0
for index, bit in enumerate(reversed(binary_list)):
#print (f"{bit=}")
#converting block of 6 bits to integer value
value += ( 2**(index%6) if bit=='1' else 0)
#print(f"{value=}")
#print(bit, end = '')
if (index+1)%6 == 0:
base64.append(Base64Encoder.base64Encoding[value])
#print(' ', end="")
#resetting value
value = 0
pass
#print()
#padding if there is less bytes and returning the result
return ''.join(reversed(base64))+''.join(['=']*bytes_to_append)
testEncoder.py
#!/usr/bin/env python3.10
from encoder import Base64Encoder
if __name__ == "__main__":
print(Base64Encoder.encode("Hello"))
print(Base64Encoder.encode("1 2 10 13 -7"))
print(Base64Encoder.encode("A"))
with open("image.jpg", "rb") as file_data:
print(Base64Encoder.encode(file_data.read()))
Output:
$ ./testEncoder.py
SGVsbG8=
MSAyIDEwIDEzIC03
QQ==

Python: how to search a multi line string for specific content

I have created a string from
connectString = 'D:\Database\10.2.0\BIN\sqlplus.exe -L sys/PASSWORD'
output = str(call(connectstring))
this results from print output
stuff stuff stuff
stuff even more stuff
ORA-28009
stuff stuff
stuff and stuff
I do
output.find('ORA-28009')
but it does not find the string sequence. The only reason I can think of is because the string is multi line. How do I handle this?
try to normalise the string removing the special charachter.
i use a function like this:
def trim (str):
str = str.replace(' ', '')
str = str.replace('\s', '')
str = str.replace('\t', '')
str = str.replace('\r', '')
str = str.replace('\n', '')
return str
Maybe you can adapt it to your case.
best,
Ste
Try replacing
output = str(call(connectstring))
with
output = str(check_output(connectstring))
which returns the bytes from the output of the command.
This is what I did to solve it. The sPath variable is needed because I have two seperate instances of Oracle on the same server. To properly test the sys account password I needed to run the sqlplus contained in the specific dir with the correct password for that instance.
def startSQLHelper(self, sPath, sPassword):
print '--starting SQL helper--'
args = [sPath + 'sqlplus.exe', '-L', 'sys/'+sPassword]
return subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
def checkOraPass (self, sPath, sPassword):
print '--checkOraPass--'
p = self.startSQLHelper(sPath, sPassword)
output = p.communicate()[0]
print output
if output.find('ORA-28009') != -1:
print 'Password passed'
return True
return False

Categories

Resources