text: #!/usr/bin/env python
  # Copyright 2014 The Chromium Authors. All rights reserved.
  # Use of this source code is governed by a BSD-style license that can be
  # found in the LICENSE file.
  
  import cStringIO
  import struct
  import sys
  
  import zipfile
  from zipfile import _ECD_SIZE, _ECD_OFFSET, _ECD_LOCATION, _ECD_SIGNATURE
  from zipfile import _CD_SIGNATURE, _CD_FILENAME_LENGTH, _CD_EXTRA_FIELD_LENGTH
  from zipfile import _CD_COMMENT_LENGTH
  from zipfile import stringEndArchive64, sizeEndCentDir64
  from zipfile import sizeEndCentDir64Locator
  from zipfile import stringCentralDir, structCentralDir
  from zipfile import sizeCentralDir
  
  
  # Heavily adapted from zipfile.py ZipFile._RealGetContents from
  # the Python 2.7 distribution.
  def _read_central_directory_offsets(zfile):
    """Read in the table of contents for the ZIP file."""
  
    fp = zfile.fp
    try:
      endrec = zipfile._EndRecData(fp)
    except IOError:
      raise zipfile.BadZipfile("File is not a zip file")
    if not endrec:
      raise zipfile.BadZipfile, "File is not a zip file"
    size_cd = endrec[_ECD_SIZE]             # bytes in central directory
    offset_cd = endrec[_ECD_OFFSET]         # offset of central directory
  
    # "concat" is zero, unless zip was concatenated to another file
    concat = endrec[_ECD_LOCATION] - size_cd - offset_cd
    if endrec[_ECD_SIGNATURE] == stringEndArchive64:
      # If Zip64 extension structures are present, account for them
      concat -= (sizeEndCentDir64 + sizeEndCentDir64Locator)
  
    # Go to start of central directory
    fp.seek(offset_cd + concat, 0)
    data = fp.read(size_cd)
    fp = cStringIO.StringIO(data)
    total = 0
    offsets = []
    while total < size_cd:
      # Tell gives use the offset inside the CD. We want the offset relative
      # to the beginning of file.
      offsets.append(fp.tell() + offset_cd + concat)
      centdir = fp.read(sizeCentralDir)
      if len(centdir) != sizeCentralDir:
        raise zipfile.BadZipfile("Truncated central directory")
      centdir = struct.unpack(structCentralDir, centdir)
      if centdir[_CD_SIGNATURE] != stringCentralDir:
        raise zipfile.BadZipfile("Bad magic number for central directory")
  
      # Skip everything else
      fp.seek(centdir[_CD_FILENAME_LENGTH]
              + centdir[_CD_EXTRA_FIELD_LENGTH]
              + centdir[_CD_COMMENT_LENGTH], 1)
  
      # update total bytes read from central directory
      total = (total + sizeCentralDir + centdir[_CD_FILENAME_LENGTH]
               + centdir[_CD_EXTRA_FIELD_LENGTH]
               + centdir[_CD_COMMENT_LENGTH])
  
    return offsets
  
  
  def reset_all_timestamps_in_zip(filename):
    """Reset all file timestamps to 1980-00-00 00:00 in a zip file.
    """
    with open(filename, 'r+b') as f:
      # Collect file headers and central directory offsets.
      zipf = zipfile.ZipFile(f)
      offsets = [zipinfo.header_offset for zipinfo in zipf.infolist()]
      cd_offsets = _read_central_directory_offsets(zipf)
  
      for offset in offsets:
        # Timestamp is four bytes starting 10 bytes after start of header.
        # https://en.wikipedia.org/wiki/Zip_(file_format)
        f.seek(offset + 10)
        f.write('\0\0\0\0')
  
      for offset in cd_offsets:
        # Timestamp is four bytes starting 12 bytes after start of each file
        # header in the central directory.
        # https://en.wikipedia.org/wiki/Zip_(file_format)
        f.seek(offset + 12)
        f.write('\0\0\0\0')
  
  
  if __name__ == '__main__':
    reset_all_timestamps_in_zip(sys.argv[1])
  