/// <summary> /// This initializes the cipher with the given password. /// See AppNote.txt for details. /// </summary> /// <param name="passphrase">The passphrase for encrypting or decrypting with this cipher. /// </param> /// <remarks> /// <code> /// Step 1 - Initializing the encryption keys /// ----------------------------------------- /// Start with these keys: /// Key(0) := 305419896 (0x12345678) /// Key(1) := 591751049 (0x23456789) /// Key(2) := 878082192 (0x34567890) /// /// Then, initialize the keys with a password: /// /// loop for i from 0 to length(password)-1 /// update_keys(password(i)) /// end loop /// /// Where update_keys() is defined as: /// /// update_keys(char): /// Key(0) := crc32(key(0),char) /// Key(1) := Key(1) + (Key(0) bitwiseAND 000000ffH) /// Key(1) := Key(1) * 134775813 + 1 /// Key(2) := crc32(key(2),key(1) rightshift 24) /// end update_keys /// /// Where crc32(old_crc,char) is a routine that given a CRC value and a /// character, returns an updated CRC value after applying the CRC-32 /// algorithm described elsewhere in this document. /// /// </code> /// <para> /// After the keys are initialized, then you can use the cipher to encrypt /// the plaintext. /// </para> /// <para> /// Essentially we encrypt the password with the keys, then discard the /// ciphertext for the password. This initializes the keys for later use. /// </para> /// </remarks> public void InitCipher(string passphrase) { byte[] p = SharedUtilities.StringToByteArray(passphrase); for (int i = 0; i < passphrase.Length; i++) { UpdateKeys(p[i]); } }
/// <summary> /// Read the next entry from the zip file. /// </summary> /// /// <remarks> /// <para> /// Call this method just before calling <see cref="Read(byte[], int, int)"/>, /// to position the pointer in the zip file to the next entry that can be /// read. Subsequent calls to <c>Read()</c>, will decrypt and decompress the /// data in the zip file, until <c>Read()</c> returns 0. /// </para> /// /// <para> /// Each time you call <c>GetNextEntry()</c>, the pointer in the wrapped /// stream is moved to the next entry in the zip file. If you call <see /// cref="Seek(long, SeekOrigin)"/>, and thus re-position the pointer within /// the file, you will need to call <c>GetNextEntry()</c> again, to insure /// that the file pointer is positioned at the beginning of a zip entry. /// </para> /// /// <para> /// This method returns the <c>ZipEntry</c>. Using a stream approach, you will /// read the raw bytes for an entry in a zip file via calls to <c>Read()</c>. /// Alternatively, you can extract an entry into a file, or a stream, by /// calling <see cref="ZipEntry.Extract()"/>, or one of its siblings. /// </para> /// /// </remarks> /// /// <returns> /// The <c>ZipEntry</c> read. Returns null (or Nothing in VB) if there are no more /// entries in the zip file. /// </returns> /// public ZipEntry GetNextEntry() { if (_findRequired) { // find the next signature long d = SharedUtilities.FindSignature(_inputStream, ZipConstants.ZipEntrySignature); if (d == -1) { return(null); } // back up 4 bytes: ReadEntry assumes the file pointer is positioned before the entry signature _inputStream.Seek(-4, SeekOrigin.Current); } _currentEntry = ZipEntry.ReadEntry(_container, !_firstEntry); _endOfEntry = _inputStream.Position; _firstEntry = true; _needSetup = true; _findRequired = false; return(_currentEntry); }
public long TruncateBackward(uint diskNumber, long offset) { // Console.WriteLine("***ZSS.Trunc to disk {0}", diskNumber); // Console.WriteLine("***ZSS.Trunc: current disk {0}", CurrentSegment); if (rw != 2) { throw new ZipException("bad state."); } // Seek back in the segmented stream to a (maybe) prior segment. // Check if it is the same segment. If it is, very simple. if (diskNumber == CurrentSegment) { return(_innerStream.Seek(offset, SeekOrigin.Begin)); } // Seeking back to a prior segment. // The current segment and any intervening segments must be removed. // First, remove the current segment. if (_innerStream != null) { _innerStream.Close(); if (File.Exists(_currentTempName)) { File.Delete(_currentTempName); } } // Now, remove intervening segments. for (uint j = CurrentSegment - 1; j > diskNumber; j--) { string s = _NameForSegment(j); // Console.WriteLine("***ZSS.Trunc: removing file {0}", s); if (File.Exists(s)) { File.Delete(s); } } // now, open the desired segment. It must exist. CurrentSegment = diskNumber; // get a new temp file, try 3 times: for (int i = 0; i < 3; i++) { try { _currentTempName = SharedUtilities.InternalGetTempFileName(); File.Move(CurrentName, _currentTempName); // move the .z0x file back to a temp name } catch (IOException) { if (i == 2) { throw; } } } _innerStream = new FileStream(_currentTempName, FileMode.Open); return(_innerStream.Seek(offset, SeekOrigin.Begin)); }