Tengo un archivo que he abierto en Python que estoy escribiendo a otro archivo de salida. Necesito que sea un múltiplo de 16 en tamaño, así que esto es lo que he concebido:

 with open(input_file, 'rb') as infile:
     with open(output_file, 'wb') as outfile:
         while True:
             input_chunk = infile.read(64)

             if len(input_chunk) == 0:
                 break
             elif len(input_chunk) % 16 > 0:
                 input_chunk.extend([0 for i in range(len(input_chunk) % 16)])

             output_file.write(input_chunk)

Por desgracia, no anexar los ceros con:

AttributeError: 'str' object has no attribute 'extend'

Primero, ¿por qué tengo una cadena de aquí, en lugar de una matriz de bytes? Estoy leyendo el archivo binario en modo binario.

Segundo, si estoy tratando con una cadena, ¿cómo puedo escribir un número de bytes con el valor 0 el final de la cadena?

las cadenas son objetos inmutables.
Tal vez input_chunk = input_chunk + ‘\0’ * (len(input_chunk) % 16)
Hay una manera que puedo leer un archivo como matrices de bytes?
Creo que el problema está en la extensión llamada.
Estás usando Python 2 o 3?

OriginalEl autor Naftuli Kay | 2013-02-19

4 Comentarios

  1. 4

    Primero, ¿por qué tengo una cadena de aquí, en lugar de una matriz de bytes?

    Porque eso es lo que file.read devuelve …

    Segundo, si estoy tratando con una cadena, ¿cómo puedo escribir un número de bytes con el valor 0 hasta el final de esa cadena?

    Usted no puede escribir en esa cadena porque las cadenas son inmutables. Sin embargo, puede escribir en una cadena diferente y crear nuevas cadenas de concatenación:

    >>> import struct
    >>> input_chunk = 'foo bar baz'
    >>> input_chunk + struct.pack('16B',*([0]*16))
    'foo bar baz\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
    >>> 

    Tenga en cuenta que si usted sabe que usted tiene 64 bytes y desea una cadena que es de 80 bytes collar con valores nulos, struct.pack rellenará automáticamente con valores nulos:

    struct.pack('80s',string_of_64_bytes)

    Para la ‘s’ de formato de carácter, el conde se interpreta como el tamaño de la cadena, no un número de repeticiones como para el otro formato de caracteres; por ejemplo, la década del ’10’ significa una sola 10-cadena de bytes, mientras que ’10c’ significa 10 caracteres. Si una cuenta no es dado, el valor predeterminado es 1. Para el embalaje, se trunca la cadena o collar con bytes nulos según corresponda para que se ajuste. Para el desembalaje, la cadena resultante siempre tiene exactamente el número especificado de bytes. Como un caso especial, ‘0’ significa que una sola cadena vacía (mientras ‘0’ significa 0 caracteres).

    Suena como el OP está tratando de hacer el cifrado AES. Si ese es el caso, entonces el relleno no debe ser todos nulos. Cabe siguiente Relleno PKCS#7 según RFC 5652 y se rellena con el byte que es el valor de cada agregado de bytes.

    OriginalEl autor mgilson

  2. 2

    En Python 2.x, un str objeto es un «array de bytes».

    Si usted necesita una matriz mutable, utilice un objeto bytearray en las versiones 2.6+:

    >>> a = bytearray('my_string')
    >>> a.extend(' hello')
    >>> str(a)
    'my_string hello'

    Lo contrario:

    >>> import array
    >>> a = array.array('c', 'my_string')
    Usted también tiene bytearray en 2.7.
    En realidad, bytearray está disponible desde 2.6 bytearray
    Que hace bytearray una mejor elección.

    OriginalEl autor JBernardo

  3. 1

    Solo uso bytearray y usted debe ser bueno como es:

               input_chunk = bytearray(infile.read(64))

    Aunque sólo quiero usar algo como [0] * (16 - len(input_chunk)%16) en lugar de una lista de comprensión para el relleno.

    OriginalEl autor Mark Reed

  4. 0

    Puede pad input_chunk como este

    input_chunk += '\x00'*(-len(input_chunk)%16)
    ¿Cómo puedo convertir un entero en un byte como este? el \x00 deberá ser dinámico, como voy a estar cambiando en lo que ser el resto de len(input_chunk)%16.

    OriginalEl autor John La Rooy

Dejar respuesta

Please enter your comment!
Please enter your name here