Migrating Python 2.6 socket.inet_aton MD5 Code to Python 3.4: Handling Bytes and Encoding
This article documents the step‑by‑step conversion of a Python 2.6 script that uses socket.inet_aton() and MD5 hashing to Python 3.4, explaining the differences in return types, required byte‑string handling, and the final optimized solution.
While implementing a feature I needed to port a script written in Python 2.6 to Python 3.4. The original code converts an IP address with socket.inet_aton() , concatenates it with a string, and computes the MD5 digest. Most of the conversion was straightforward, but the socket.inet_aton() part caused several type‑related errors.
The original Python 2.6 code:
#!python2
# -*- coding: utf-8 -*-
import socket
import hashlib
if __name__ == '__main__':
ip = '192.168.1.12'
base_str = 'testSTR'
ip_md5 = hashlib.md5(socket.inet_aton(ip) + base_str).digest().encode('hex')
print(ip_md5)Running it produced the MD5 hash fc138bb4748a18f885cc321c2c6396e2 . When the same script was executed under Python 3.4, it raised a TypeError: can't concat bytes to str because socket.inet_aton() now returns a bytes object.
Documentation shows that in Python 2.6 the function returns a bytes object (four characters), while in Python 3.4 it returns a str . To keep the original logic, I first tried decoding the bytes to a string using the gbk codec and then concatenating:
#!python3
# -*- coding: utf-8 -*-
import socket
import hashlib
if __name__ == '__main__':
ip = '192.168.1.12'
base_str = 'testSTR'
str_md5 = socket.inet_aton(ip).decode('gbk') + base_str
ip_md5 = hashlib.md5(str_md5).digest().encode('hex')
print(ip_md5)This produced a new error: Unicode-objects must be encoded before hashing . The difference is that in Python 3 the hashlib.md5() function expects a bytes‑like object. I then encoded the string back to bytes, but another error appeared because the result of .encode() was already a bytes object, and calling .encode() again is invalid.
After consulting the documentation for hash.digest() (which returns a bytes object in Python 3), I switched to using binascii.hexlify() to obtain the hexadecimal representation:
#!python3
# -*- coding: utf-8 -*-
import socket
import hashlib
import binascii
if __name__ == '__main__':
ip = '192.168.1.12'
base_str = 'testSTR'
str_md5 = socket.inet_aton(ip).decode('gbk') + base_str
ip_md5 = binascii.hexlify(hashlib.md5(str_md5.encode('gbk')).digest()).decode()
print(ip_md5)This produced the expected hash fc138bb4748a18f885cc321c2c6396e2 . However, the intermediate decode/encode steps are unnecessary. A cleaner solution is to keep everything as bytes :
#!python3
# -*- coding: utf-8 -*-
import socket
import hashlib
import binascii
if __name__ == '__main__':
ip = '192.168.1.12'
base_str = 'testSTR'
str_md5 = socket.inet_aton(ip) + base_str.encode()
ip_md5 = binascii.hexlify(hashlib.md5(str_md5).digest()).decode()
print(ip_md5)Summary of lessons learned:
Python 3 introduced a distinct bytes type; understanding when a function returns bytes versus str is crucial, especially regarding encoding.
Always check the actual implementation of library functions rather than relying on assumptions or superficial observations.
Maintain a clear problem‑solving mindset; guessing often leads to wasted effort.
Identify the root cause first and address it directly for more efficient debugging.
360 Quality & Efficiency
360 Quality & Efficiency focuses on seamlessly integrating quality and efficiency in R&D, sharing 360’s internal best practices with industry peers to foster collaboration among Chinese enterprises and drive greater efficiency value.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.