Abs
Abs

Reputation: 57946

How to zip a string?

What is the equivalent of this class in python? https://gist.github.com/2594962

In PHP, it allows you to zip a string.

I'm trying to find the equivaelnt in the following languages: Python, Ruby on Rails and ASP.

I'm hoping there are built in functions for these languages. I couldn't find one in PHP.

Update

When I say Zip, I am referring to the standard algorithm that windows uses. Not in the sense of an archive. I currently use that class to zip a string, base64 encode it and send it as a request to an internal API.

Upvotes: 16

Views: 35506

Answers (4)

shmnff
shmnff

Reputation: 739

import os
import zipfile

content = 'foo bar'
filename = 'test.txt'
zipfile_name = 'test.zip'
zipfile_path = os.path.join('/tmp', zipfile_name)
with zipfile.ZipFile(zipfile_path, 'w', zipfile.ZIP_DEFLATED) as z:
    z.writestr(filename, content)
    

Upvotes: 0

martineau
martineau

Reputation: 123491

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.'

Upvotes: 25

yak
yak

Reputation: 9041

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)

Upvotes: 8

Israel Unterman
Israel Unterman

Reputation: 13510

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

Upvotes: 7

Related Questions