I'm trying to convert binary to decimal to ASCII. Using this code, I'm able to take a binary input and split it into chunks of 7 bits.
def binary_to_ascii7bits(bstring):
n = 7
byte = [bstring[i:i+n] for i in range(0, len(bstring), n)]
print(byte)
I need to be able to turn each 7-bit substring into a decimal number in order to use the chr function. If I try to turn this list into a string, it prints for example, "['1111000']", but I cannot have the brackets and apostrophes in the string. What can I do to fix this?
First of all, for the chr function it should be an integer, not a decimal.
Add this list comprehension before the print function -
byte = [chr(64 + int(i)) for i in byte]
This will give the string for the bytes. I think this is what you want.
You can add just one more line (as below) to achieve what you described.
You have int(..., 2) to convert the string representation of a binary number into an integer. Then apply chr to get a character. This procedure is done using (list) comprehension, so that the result is a list of characters. Then use join to make a single string.
text = '1111000' * 10
def binary_to_ascii7bits(bstring):
n = 7
byte = [bstring[i:i+n] for i in range(0, len(bstring), n)]
return ''.join(chr(int(x, 2)) for x in byte)
print(binary_to_ascii7bits(text)) # xxxxxxxxxx
Related
I've got a 4 number string corresponding to the code-point of an unicode character.
I need to dynamically convert it to its unicode character to be stored inside a variable.
For example, my program will spit during its loop a variable a = '0590'. (https://www.compart.com/en/unicode/U+0590)
How do I get the variable b = '\u0590'?
I've tried string concatenation '\u' + a but obviously it's not the way.
chr will take a code point as an integer and convert it to the corresponding character. You need to have an integer though, of course.
a = '0590'
result = chr(int(a))
print(result)
On Python 2, the function is called unichr, not chr. And if you want to interpret the string as a hex number, you can pass an explicit radix to int.
a = '0590'
result = unichr(int(a, 16))
print(result)
I have been trying to convert an integer into a string. My codes are as follows:
n = 357
x = str(n)
print x
The problem is that online editors that I have tried are not printing the string as '357'. Instead the string is printed as 357. What have I been doing wrong?
You apparently want to print the representation of the string. Python has a builtin function repr(..) for this:
n = 357
x = str(n)
print(repr(x))
The representation of a string is a list of characters between single or double quotes (double quotes if the string contains at least one single quote and no double quotes). Furthermore if there are escape sequences (like a new line), these are printed with a backslash (like \n).
I need to port code from perl that packs byte string. In perl it looks like the following:
pack 'B*', '0100001000111110010100101101000010010001'
I don't see B* format analog in python struct module. Perhaps there are ready solutions not to invent a bicycle?
Honestly, description is not clear for me, so i even can't imagine how it works to implement it by myself:
Likewise, the b and B formats pack a string that's that many bits
long. Each such format generates 1 bit of the result. These are
typically followed by a repeat count like B8 or B64 .
Each result bit
is based on the least-significant bit of the corresponding input
character, i.e., on ord($char)%2. In particular, characters "0" and
"1" generate bits 0 and 1, as do characters "\000" and "\001" .
Starting from the beginning of the input string, each 8-tuple of
characters is converted to 1 character of output.
With format b , the
first character of the 8-tuple determines the least-significant bit of
a character; with format B , it determines the most-significant bit of
a character.
If the length of the input string is not evenly divisible
by 8, the remainder is packed as if the input string were padded by
null characters at the end. Similarly during unpacking, "extra" bits
are ignored.
If the input string is longer than needed, remaining
characters are ignored.
A * for the repeat count uses all characters
of the input field. On unpacking, bits are converted to a string of 0
s and 1 s.
So, string is divided in chunks for 8 symbols. If last chunk is less 8 symbols, it is padded with null characters in the end to be 8 symbols. Then, each chunk becomes a byte.
But i can't understand, what are resulting bits? What is meant under B8 and B64 here?
The int-object has a to_bytes-method:
binary = '0100001000111110010100101101000010010001'
number = int(binary, 2)
print(number.to_bytes((number.bit_length()+7)//8, 'big'))
# b'B>R\xd0\x91'
I'm not sure of the exact perl semantics, but here's my guess at them:
def pack_bit_string(bs):
ret = b''
while bs:
chunk, bs = bs[:8], bs[8:]
# convert to an integer so we can pack it
i = int(chunk, 2)
# Handle trailing chunks that are not 8 bits
# Note this as an augmented assignment, perhaps also read as
# i = i << (8 - len(chunk))
i <<= 8 - len(chunk)
ret += struct.pack('B', i)
return ret
Comments are inline. If you know things like "the input is less than 64 bits" you can avoid the loop and use Q for struct.pack
The part where I need to go from the number values I obtained to characters to spell out a word it not working, it says I need to use an integer for the last part?
accept string
print "This program reduces and decodes a coded message and determines if it is a palindrome"
string=(str(raw_input("The code is:")))
change it to lower case
string_lowercase=string.lower()
print "lower case string is:", string_lowercase
strip special characters
specialcharacters="1234567890~`!##$%^&*()_-+={[}]|\:;'<,>.?/"
for char in specialcharacters:
string_lowercase=string_lowercase.replace(char,"")
print "With the specials stripped out the string is:", string_lowercase
input offset
offset=(int(raw_input("enter offset:")))
conversion of text to ASCII code
result=[]
for i in string_lowercase:
code=ord(i)
result.append([code-offset])
conversion from ASCII code to text
text=''.join(chr(i) for i in result)
print "The decoded string is:", text.format(chr(result))
It looks like you have a list of lists instead of a list of ints when you call result.append([code-offset]). This means later when you call chr(i) for i in result, you are passing a list instead of an int to chr().
Try changing this to result.append(code-offset).
Other small suggestions:
raw_input already gives you a string, so there's no need to explicitly cast it.
Your removal of special characters can be more efficiently written as:
special_characters = '1234567890~`!##$%^&*()_-+={[}]|\:;'<,>.?/'
string_lowercase = ''.join(c for c in string_lowercase if string not in special_characters)
This allows you to only have to iterate through string_lowercase once instead of per character in special_characters.
While doing .append() to list, use code-offset instead of [code-offset]. As in later you are storing the value as a list (of one ASCII) instead of storing the ASCII value directly.
Hence your code should be:
result = []
for i in string_lowercase:
code = ord(i)
result.append(code-offset)
However you may simplified this code as:
result = [ord(ch)-offset for ch in string_lowercase]
You may even further simplify your code. The one line to get decoded string will be:
decoded_string = ''.join(chr(ord(ch)-offset) for ch in string_lowercase)
Example with offset as 2:
>>> string_lowercase = 'abcdefghijklmnopqrstuvwxyz'
>>> offset = 2
>>> decoded_string = ''.join(chr(ord(ch)-offset) for ch in string_lowercase)
>>> decoded_string
'_`abcdefghijklmnopqrstuvwx'
You are passing a list to chr when it only accepts integers. Try result.append(code-offset). [code-offset] is a one-item list.
Specifically, instead of:
result=[]
for i in string_lowercase:
code=ord(i)
result.append([code-offset])
use:
result=[]
for i in string_lowercase:
code=ord(i)
result.append(code-offset)
If you understand list comprehension, this works too: result = [ord(i)-offset for i in string_lowercase]
Given a long string such as:
"fkjdlfjzgjkdsheiwqueqpwnvkasdakpp"
or
"0.53489082304804918409853091868095809846545421135498495431231"
How do I find the value of the nth character in that string? I could solve this if I could convert it into a list (where each digit gets it's own index) but since the numbers aren't separated by commas I don't know how to do this either.
AFAIK there is no command like string.index(10) which would return the 11th character in.
strings are like lists. so you can access them the same way,
>>> a = "fkjdlfjzgjkdsheiwqueqpwnvkasdakpp"
>>> print a[10]
k
Strings are iterable and indexable (since it is a sequence type), so you can just use:
"fkjdlfjzgjkdsheiwqueqpwnvkasdakpp"[10]
To get the corresponding character in the nth value, just use this function:
def getchar(string, n):
return str(string)[n - 1]
Example usage:
>>> getchar('Hello World', 5)
'o'