Copyright (C) 2017-2026, Daniel Roethlisberger.
https://www.roe.ch/acefile
pip install acefile
# python library
import acefile
with acefile.open('example.ace', encoding='cp850') as f:
f.extractall()
# unace utility
acefile-unace -x example.ace
This single-file, pure python 3, no-dependencies implementation is intended to be used as a library, but also provides a stand-alone unace utility. As mostly pure-python implementation, it is significantly slower than native implementations, but more robust against vulnerabilities.
This implementation supports up to version 2.0 of the ACE archive format, including the EXE, DELTA, PIC and SOUND modes of ACE 2.0, password protected archives and multi-volume archives. It does not support writing to archives. It is an implementation from scratch, based on the 1998 document titled "Technical information of the archiver ACE v1.2" by Marcel Lemke, using unace 2.5 and WinAce 2.69 by Marcel Lemke as reference implementations.
For more information, API documentation, source code, packages and release notifications, refer to:
- https://www.roe.ch/acefile
- https://apidoc.roe.ch/acefile
- https://github.com/droe/acefile
- https://pypi.python.org/pypi/acefile
- https://infosec.exchange/@droe
Python 3. No other dependencies.
pip install acefile
The acefile package includes an optional acebitstream module that
implements the bit stream class in c, resulting in a 50% speedup.
It is automatically used wherever it builds cleanly, but is not required.
Extract all files in the archive, with directories, to current working dir:
import acefile
with acefile.open('example.ace') as f:
f.extractall()
Walk all files in the archive and test each one of them:
import acefile
with acefile.open('example.ace') as f:
for member in f:
if member.is_dir():
continue
if f.test(member):
print("CRC OK: %s" % member.filename)
else:
print("CRC FAIL: %s" % member.filename)
In-memory decompression of a specific archive member:
import acefile
import io
filelike = io.BytesIO(b'\x73\x83\x31\x00\x00\x00\x90**ACE**\x14\x14' ...)
with acefile.open(filelike) as f:
data = f.read('example.txt')
Handle archives potentially containing large members in chunks to avoid fully reading them into memory:
import acefile
with acefile.open('large.ace') as fi:
with open('large.iso', 'wb') as fo:
for block in fi.readblocks('large.iso'):
fo.write(block)
Filenames in ACE archives are stored in whatever local OEM/ANSI code page in use on the archiving system, without any indication in the archive format as to which code page that might be. Since acefile 0.6.15, the code page can be specified if it is known, otherwise utf-8 is used by default, matching the behaviour of older versions of acefile.
with acefile.open('example.ace', encoding='cp437') as f:
f.extractall()
Check the API documentation for a complete description of the API.
Extract all files in the archive, with directories, to current working dir:
acefile-unace -x --encoding cp850 example.ace
Test all files in the archive, verbosely:
acefile-unace -tv --encoding cp850 example.ace
List archive contents, verbosely:
acefile-unace -lv --encoding cp850 example.ace
Check usage for more functionality:
acefile-unace -h
This project uses docstrings for unit testing:
./acefile.py --doctest
This project uses pytest for integration testing, recursively looking for
corpora of ACE archives in ../acefile-testdata/ and
../acefile-testdata-private/. The former is intended for a checkout of
droe/acefile-testdata. The latter
is intended for a developer-local test corpus that might be impractically large
or contain data that cannot be redistributed. Both are optional, the
integration tests are currently not useful without any test archives though.
git clone https://github.com/droe/acefile-testdata.git ../acefile-testdata
pytest -v
The author's private test corpus consists of ~ 4500 ACE archives, the bulk of which from the following sources:
- Discmaster / Archive.org
- Morrowind ModHistory (offline)
- Sembiance file format samples
- wdlkmpx/unace1 (unace 1.2b fork)
- VirusTotal retrohunt from 2019
If you are aware of other corpora of ACE archives, please open an issue on GitHub so that they can be incorporated into testing too.
Marcel Lemke for designing the ACE archive format and ACE compression and decompression algorithms.