Python equivalente a la utilidad de “cadenas” de Unix

Estoy tratando de escribir un script que extraiga cadenas de un binario ejecutable y las guarde en un archivo. Tener este archivo separado por una nueva línea no es una opción, ya que las cadenas pueden tener nuevas líneas. Sin embargo, esto también significa que el uso de la utilidad de “cadenas” de Unix no es una opción, ya que simplemente imprime todas las cadenas separadas por líneas nuevas, lo que significa que no hay forma de saber qué cadenas tienen líneas nuevas incluidas solo con mirar la salida de “instrumentos de cuerda”. Por lo tanto, esperaba encontrar una función o biblioteca de python que implemente la misma funcionalidad de “cadenas”, pero que me dé esas cadenas como variables para poder evitar el problema de nueva línea.

¡Gracias!

Aquí hay un generador que produce todas las cadenas de caracteres imprimibles> = min (4 de forma predeterminada) en longitud que encuentra en el filename de filename :

 import string def strings(filename, min=4): with open(filename, errors="ignore") as f: # Python 3.x # with open(filename, "rb") as f: # Python 2.x result = "" for c in f.read(): if c in string.printable: result += c continue if len(result) >= min: yield result result = "" if len(result) >= min: # catch result at EOF yield result 

Que puedes iterar sobre:

 for s in strings("something.bin"): # do something with s 

… o almacenar en una lista:

 sl = list(strings("something.bin")) 

He probado esto muy brevemente, y parece dar el mismo resultado que el comando de strings Unix para el archivo binario arbitrario que elegí. Sin embargo, es bastante ingenuo (para empezar, lee todo el archivo en la memoria de una vez, lo que puede ser costoso para archivos grandes), y es muy poco probable que se aproxime al rendimiento del comando de strings Unix.

Para citar las man strings :

 STRINGS (1) Herramientas de desarrollo de GNU STRINGS (1)

 NOMBRE
        cadenas: imprima las cadenas de caracteres imprimibles en archivos.

 [...]
 DESCRIPCIÓN
        Para cada archivo dado, las cadenas GNU imprimen el carácter imprimible
        secuencias que tienen al menos 4 caracteres de largo (o el número dado con
        las opciones a continuación) y son seguidas por un carácter no imprimible.  Por
        por defecto, solo imprime las cadenas desde el inicializado y cargado
        secciones de archivos de objetos;  para otros tipos de archivos, imprime el
        cadenas de todo el archivo.

Podría lograr un resultado similar utilizando una regex coincida con al menos 4 caracteres imprimibles. Algo como eso:

 >>> import re >>> content = "hello,\x02World\x88!" >>> re.findall("[^\x00-\x1F\x7F-\xFF]{4,}", content) ['hello,', 'World'] 

Tenga en cuenta que esta solución requiere que todo el contenido del archivo se cargue en la memoria.

Puede usar el paquete csv, que administra las nuevas líneas en cadenas. Solo necesitas una columna.