13

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.

gen_Eric
  • 223,194
  • 41
  • 299
  • 337
Abs
  • 56,052
  • 101
  • 275
  • 409
  • 4
    What do you mean by `zip` here? – Gareth Latty May 04 '12 at 14:06
  • 2
    "zip a string"? That doesn't really mean anything to me. Could you try a few examples? – Devin Jeanpierre May 04 '12 at 14:06
  • PHP has a built-in [`ZipArchive`](http://php.net/manual/en/class.ziparchive.php) class. – gen_Eric May 04 '12 at 14:07
  • @Rocket can that be used to Zip a string - or do you have to zip a file then read the contents out of it? – Abs May 04 '12 at 14:08
  • 1
    So, to clarify, you mean compress in a zip archive? – Gareth Latty May 04 '12 at 14:08
  • @Abs: It can be used to make/read zip files. – gen_Eric May 04 '12 at 14:08
  • @Abs barring anything else, you can always write the string to a file and then zip that file. It doesn't make much sense to say 'zip a string' – Jeff Lambert May 04 '12 at 14:08
  • Python has a [`zipfile`](http://docs.python.org/library/zipfile.html) library. – gen_Eric May 04 '12 at 14:09
  • @watcher it does if you want to send a large string to an API. – Abs May 04 '12 at 14:10
  • @Abs: Have a look at [`ZipArchive::addFromString`](http://www.php.net/manual/en/ziparchive.addfromstring.php) – gen_Eric May 04 '12 at 14:10
  • @Rocket thanks I wasn't aware of that PHP function. Btw, who ever down voted me feel free to +1 as I have explained what I meant by "zip a string". ;) – Abs May 04 '12 at 14:14
  • @Abs then you 'compress' the data, in which case you're looking for a string compression algorithm: http://stackoverflow.com/questions/1138345/best-compression-algorithm-for-short-text-strings. – Jeff Lambert May 04 '12 at 14:37
  • @watcher you are probably right, but it has to be something that is common in most languages as a built in function as this will be the way users make a request to an API. – Abs May 04 '12 at 14:48
  • @Abs: Actually you *have never* really explained what you mean by "zip a string". i.e. Whether it means to turn a string into a zip archive or just compress it the same way the data in one is. Likewise, saying "the standard algorithm that windows uses" doesn't convey much information. – martineau Jan 08 '22 at 18:37

3 Answers3

26

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.'
martineau
  • 119,623
  • 25
  • 170
  • 301
7

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)
yak
  • 8,851
  • 2
  • 29
  • 23
5

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

Israel Unterman
  • 13,158
  • 4
  • 28
  • 35
  • When you print s, is that the compressed version of the string? – Abs May 04 '12 at 14:24
  • By default, `ZipFile` doesn't compress. You have to use the `ZIP_DEFLATED` argument. See the docs. – yak May 04 '12 at 15:57
  • @Abs: `s` is a `StringIO` object which is a memory-resident file-like object, so while it will contain the compressed string, it also has a number of other things that make up the format of a `.zip` file (such as a header), as well as who-knows-what type of internal stuff that is used to maintain the data in memory. – martineau Dec 21 '17 at 14:12