By david

2019-11-08 14:37:25 8 Comments

I'm trying to convert string to binary and take one's complement, after that display the string again. i have seen a couples of related post such as here and here and i'm follow the official work where have been posted in here, in the below code after run the code its showing error AttributeError: 'bytes' object has no attribute 'encode'. i'm using python 3.6

the below code is :

import binascii

def text_to_bits(text, encoding='utf-8', errors='surrogatepass'):
    bits = bin(int(binascii.hexlify(text.encode(encoding, errors)), 16))[2:]
    return bits.zfill(8 * ((len(bits) + 7) // 8))

def text_from_bits(bits, encoding='utf-8', errors='surrogatepass'):
    n = int(bits, 2)
    return int2bytes(n).decode(encoding, errors)

def int2bytes(i):
    hex_string = '%x' % i
    n = len(hex_string)
    return binascii.unhexlify(hex_string.zfill(n + (n & 1)))
b=your_string.encode('ascii', 'strict')

is there a way after convert it to binary to take one's complement of it and display the string again?


@Error - Syntactical Remorse 2019-11-08 15:18:30

I feel like you could do this easier:

st = "hello world"
my_binary = ' '.join(format(ord(x), 'b') for x in st)

original = ''.join(chr(int(X[:8], 2)) for X in my_binary.split())


Then just do twos-compliment on the string with something like:

def binary_str_twos(bin_str):
    twos = []
    first_one = True
    # twos compliment
    for char in reversed(bin_str):
        if char == ' ':
        elif char == '1':
            twos.append('1' if first_one else '0')
            if first_one:
                first_one = False
            twos.append('0' if first_one else '1')

    return ''.join(reversed(twos))

Note that this isn't as efficient as working with binary only.

-- Edit -- Working in 8-bit binary without spaces:

st = "hello world"
my_binary = ''.join(format(ord(x), '08b') for x in st)

original = ''.join(chr(int(my_binary[i:i+8], 2)) for i in range(0, len(my_binary), 8))

@david 2019-11-08 15:28:47

good job sir,thanks, just one thing , how i can remove the spaces in between the bits? in the result shown 1101000 1100101 1101100 1101100 1101111 100000 1110111 1101111 1110010 1101100 1100100 ? i want fully series binary such like (11010001100101110110011011001101111100000111011111011111110‌​010 11011001100100 )

@Error - Syntactical Remorse 2019-11-08 15:32:28

You can either change the logic to use ''.join(...) instead of ' '.join(...) or just do print(''.join(my_binary.split())). Though option 1 would be faster in the long run.

@david 2019-11-08 15:37:31

thx again sir, i follow what you said , i got this output (11010001100101110110011011001101111100000111011111011111110‌​01011011001100100 Ñ) so the word , hello world display!

@Error - Syntactical Remorse 2019-11-08 15:42:12

@david See my update for working without spaces. ( You may want to work with 16 bits instead of 8 (' '.join(format(ord(x), '016b')

@david 2019-11-08 15:49:04

@Error-Syntavtical Remorse , i appreciate your perfect work. thank you sir.

@tevemadar 2019-11-08 15:15:03

If supporting ASCII is enough, you can do this:

a="Hello World!"
b="".join(bin(ord(x)^255)[2:] for x in a)
c="".join(chr(int(b[x:x+8],2)^255) for x in range(0,len(b),8))

Hello World!

since ASCII codes are below 128, someASCII ^ 255 (the one's complement) is always going to be a 8-bit number (the most significant bit gets set). bin() prepends a 0b prefix, that is what the [2:] gets rid of.

If you need it for generic bytes, some padding magic has to be applied, like

b="".join(("0000000"+bin(ord(x))[2:])[-8:] for x in a)

@david 2019-11-08 15:24:29

thx sir for good explain. but which version python are you using? i'm trying your code in python 3.6 and showing b="".join(bin(ord(x)^255)[2:] for x in a) TypeError: 'str' object is not callable

@tevemadar 2019-11-08 17:25:42

@david I was using 3.6.3 in particular. It seems to work fine on Ideone too:

@âńōŋŷXmoůŜ 2019-11-08 14:52:25

No need to convert your string into unicode (encode). Your functions work very well. Look at the code below:

#b=your_string.encode('ascii', 'strict')
b = text_to_bits(your_string)
t = text_from_bits(b)



@david 2019-11-08 15:00:13

thanks sir, i think you are using python 2, in python 3 it's showing TypeError: 'str' object is not callable , so i was trying to solve the problem by convert str to bytes first like your_string.encode('ascii', 'strict') , but showing another error message is AttributeError: 'bytes' object has no attribute 'encode'

@âńōŋŷXmoůŜ 2019-11-08 15:39:58

I am using 3.6.5 python --version Python 3.6.5 :: Anaconda, Inc.

@david 2019-11-08 15:44:11

i'm using 3.6.4 and still not able to run the code give me same error

Related Questions

Sponsored Content

12 Answered Questions

[SOLVED] Converting integer to string?

14 Answered Questions

[SOLVED] How do I get a substring of a string in Python?

13 Answered Questions

[SOLVED] Calling a function of a module by using its name (a string)

  • 2008-08-06 03:36:08
  • ricree
  • 717406 View
  • 1758 Score
  • 13 Answer
  • Tags:   python object

19 Answered Questions

[SOLVED] Convert bytes to a string

5 Answered Questions

[SOLVED] How do I lowercase a string in Python?

27 Answered Questions

[SOLVED] How do I parse a string to a float or int?

3 Answered Questions

[SOLVED] Best way to convert string to bytes in Python 3?

10 Answered Questions

[SOLVED] Does Python have a string 'contains' substring method?

20 Answered Questions

[SOLVED] Converting string into datetime

  • 2009-01-21 18:00:29
  • Oli
  • 3009950 View
  • 2205 Score
  • 20 Answer
  • Tags:   python datetime

Sponsored Content