How to zip a string?

To compress a string using the same method used in .zip archives, just use the zlib module directly (which is what Python's zipfile module does). Here's a simple example:

import zlib

teststr = """Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus
pretium justo eget elit eleifend, et dignissim quam eleifend. Nam vehicula nisl
posuere velit volutpat, vitae scelerisque nisl imperdiet. Phasellus dignissim,
dolor amet."""

cmpstr = zlib.compress(teststr.encode('utf-8'))
uncmpstr = zlib.decompress(cmpstr)

fmt = '{:>8}: (length {}) {!r}'
print(fmt.format('teststr', len(teststr), teststr))
print(fmt.format('cmpstr', len(cmpstr), cmpstr))
print(fmt.format('uncmpstr', len(uncmpstr), uncmpstr))

Output:

 teststr: (length 237) 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus\npretium justo eget elit eleifend, et dignissim quam eleifend. Nam vehicula nisl\nposuere velit volutpat, vitae scelerisque nisl imperdiet. Phasellus dignissim,\ndolor amet.'
  cmpstr: (length 157) 'x\x9cMO[\x0e\xc30\x08\xfb\xef)8@\xd5\x93L\xd3\xae\x10%^\xcb\x94W\x03\xf4\xfc\xa3\x9d\xb4\xed\x07\tcc\xfb\xd6\x06\nq\x17+\x94Zn\x83\x84\x95B\x81\xce\x14[\x15D\x85\xda\xa0\x90\xb8\xb3D\xae+!\xb3.\xf4\xd8\x82 g\x93\xa9\x0f(\xbb\xfce\xa2\x8d\xb0B/\x8a\x0f\xf0\x135\xcd\xe4H\xe2\xb5\xb2\x08\x17\xda-\x94\xefm\xa1\xbbo\x076\x8e\x96\x039%O\xbd\x89a\xc0\xd1\xf3\xcb\xd1\xb2i\x0f\x1e\xe7`\r \x89\xae\x1d,\xbb\xe1\xa2\x13\x97\x8e\x91\x18\xff\x99~v\xf3\xf4iu6Z\xde\xf8\xa6X\r'
uncmpstr: (length 237) 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus\npretium justo eget elit eleifend, et dignissim quam eleifend. Nam vehicula nisl\nposuere velit volutpat, vitae scelerisque nisl imperdiet. Phasellus dignissim,\ndolor amet.'

I don't know it exactly what you need but you might find this interesting. I use here the zipfile module with a string-file-like object

import zipfile
import StringIO

s = StringIO.StringIO()  # s is a file like object
z = zipfile.ZipFile(s, 'w')  # this is a zip archive
z.writestr('file1.txt', 'Hello, world') # create a "file" inside the archive called 'file1.txt' and write 'hello world' into it
z.close() # close the archive

print s.getvalue()  # this is the content of the string
s.close()  # close the string file-like object

Watch the PK start inside the string


Python has a zipfile module which allows you to read/write zip archives.

The zipfile.ZipFile class has a writestr() method that can create a "file" in the archive directly from a string.

So no, you don't have to write your string to a file before archiving it.

Update after question edit

You say you don't want an archive but the linked PHP code does just that -- creates a PK-Zip archive. In Python you do the same with zipfile. Here's an example that creates a zip and adds one file to it -- all in-memory, without physical files.

import zipfile
from cStringIO import StringIO

f = StringIO()
z = zipfile.ZipFile(f, 'w', zipfile.ZIP_DEFLATED)
z.writestr('name', 'some_bytes_to_compress')
z.close()

output_string = f.getvalue()

output_string will be the compressed content in PK-Zip format.

If you control both sending and receiving side and you don't need to send multiple compressed files in one chunk of data, using PK-Zip is overkill. Instead, you could just use the zlib module which implements the compression for PK-Zip.

import zlib

output_string = zlib.compress('some_bytes_to_compress')

And then you can decompress it (assuming Python):

decompressed_string = zlib.decompress(output_string)

Under Python, you are looking for the zipfile module - specifically ZipFile.writestr().

I'd note that in general, zlib is used a lot more for the kind of uses you are talking about.