<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://emuverse.ru/w/index.php?action=history&amp;feed=atom&amp;title=%D0%A3%D0%9A%D0%9D%D0%A6_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D1%8B_%D0%B0%D1%80%D1%85%D0%B8%D0%B2%D0%BE%D0%B2</id>
	<title>УКНЦ форматы архивов - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://emuverse.ru/w/index.php?action=history&amp;feed=atom&amp;title=%D0%A3%D0%9A%D0%9D%D0%A6_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D1%8B_%D0%B0%D1%80%D1%85%D0%B8%D0%B2%D0%BE%D0%B2"/>
	<link rel="alternate" type="text/html" href="https://emuverse.ru/w/index.php?title=%D0%A3%D0%9A%D0%9D%D0%A6_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D1%8B_%D0%B0%D1%80%D1%85%D0%B8%D0%B2%D0%BE%D0%B2&amp;action=history"/>
	<updated>2026-04-25T02:27:11Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.40.0</generator>
	<entry>
		<id>https://emuverse.ru/w/index.php?title=%D0%A3%D0%9A%D0%9D%D0%A6_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D1%8B_%D0%B0%D1%80%D1%85%D0%B8%D0%B2%D0%BE%D0%B2&amp;diff=4036&amp;oldid=prev</id>
		<title>Nzeemin: Новая страница: «{{ДИ|Источни=https://zx-pk.ru/threads/32934-format-arkhiva-lza.html}}  === LZS/LZA === Программы: * LZ.SAV - упаковщик LZS * UZ.SAV - распаковщик LZS программы с правками от EmeSoft: * LZA.SAV - упаковщик LZA * UZA.SAV - распаковщик LZA Правки: # для упаковщика уменьшен буфер в 2 раза, соответственно памяти требуется...»</title>
		<link rel="alternate" type="text/html" href="https://emuverse.ru/w/index.php?title=%D0%A3%D0%9A%D0%9D%D0%A6_%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D1%8B_%D0%B0%D1%80%D1%85%D0%B8%D0%B2%D0%BE%D0%B2&amp;diff=4036&amp;oldid=prev"/>
		<updated>2026-03-05T21:09:05Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «{{ДИ|Источни=https://zx-pk.ru/threads/32934-format-arkhiva-lza.html}}  === LZS/LZA === Программы: * LZ.SAV - упаковщик LZS * UZ.SAV - распаковщик LZS программы с правками от EmeSoft: * LZA.SAV - упаковщик LZA * UZA.SAV - распаковщик LZA Правки: # для упаковщика уменьшен буфер в 2 раза, соответственно памяти требуется...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{ДИ|Источни=https://zx-pk.ru/threads/32934-format-arkhiva-lza.html}}&lt;br /&gt;
&lt;br /&gt;
=== LZS/LZA ===&lt;br /&gt;
Программы:&lt;br /&gt;
* LZ.SAV - упаковщик LZS&lt;br /&gt;
* UZ.SAV - распаковщик LZS&lt;br /&gt;
программы с правками от EmeSoft:&lt;br /&gt;
* LZA.SAV - упаковщик LZA&lt;br /&gt;
* UZA.SAV - распаковщик LZA&lt;br /&gt;
Правки:&lt;br /&gt;
# для упаковщика уменьшен буфер в 2 раза, соответственно памяти требуется сильно меньше.&lt;br /&gt;
# сжатые данные инвертированы, но КС считается по неинвертированным данным&lt;br /&gt;
# изменён текст, сделаны незначительные оптимизации.&lt;br /&gt;
&lt;br /&gt;
формат Архива:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
struct ArchHeader {             // заголовок архива&lt;br /&gt;
    word    archID = EmeSoft ? ^R&amp;lt;LZA&amp;gt; : ^R&amp;lt;LZS&amp;gt;; // сигнатура&lt;br /&gt;
    word    version = &amp;quot;21&amp;quot;;     // версия архива&lt;br /&gt;
    word    N;                  // размер кольцевого буфера в байтах 010000 или 04000 для EmeSoft&lt;br /&gt;
    word    date;               // дата создания архива&lt;br /&gt;
    word    password;           // зашифрованный пароль для распаковки, 0, если нету.&lt;br /&gt;
            /* пароль шифруется так:&lt;br /&gt;
               password = comb(swab(^R&amp;lt;nnn&amp;gt; xor archID)),&lt;br /&gt;
               где nnn - открытый пароль, заданный в ключе /P */&lt;br /&gt;
    word    0;                  // зарезервировано&lt;br /&gt;
    word    archCatSize;        // размер каталога архива в байтах, 0 - если нет каталога&lt;br /&gt;
    word    archCatBlk;         // номер блока начала каталога, относительно начала файла архива,&lt;br /&gt;
                                // 0 - если нет каталога&lt;br /&gt;
                                // каталог архива выравнивается по границе блока.&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
struct FileHeader {             // заголовок файла&lt;br /&gt;
    dword   .rad50 &amp;quot;FILNAM&amp;quot;;    // имя файла в RADIX-50&lt;br /&gt;
    word    .rad50 &amp;quot;EXT&amp;quot;        // расширение файла в RADIX-50&lt;br /&gt;
    word    unpSizeBlk;         // размер файла в блоках до архивации&lt;br /&gt;
    word    date;               // дата создания файла&lt;br /&gt;
    word    CS;                 // контрольная сумма упакованного массива&lt;br /&gt;
    dword   pckSize;            // размер упакованного массива в байтах&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
struct ArchCatRecord {  // запись о файле в каталоге архива&lt;br /&gt;
    word    blkNum;     // номер блока относительно начала файла архива, с которого начинается файл в архиве&lt;br /&gt;
    word    offset;     // смещение в блоке, с которого начинается массив упакованных данных файла&lt;br /&gt;
    FileHeader file;    // структура заголовка файла&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// формат Архива&lt;br /&gt;
Archive {&lt;br /&gt;
    ArchHeader header;      // заголовок архива&lt;br /&gt;
    {&lt;br /&gt;
        FileHeader fh;      // заголовок файла&lt;br /&gt;
        byte[fh.pckSize];   // упакованный массив&lt;br /&gt;
        .wordeven           // выравнивание по слову&lt;br /&gt;
    } по количеству файлов в архиве;&lt;br /&gt;
&lt;br /&gt;
    .blockeven                  // выравнивание по блоку&lt;br /&gt;
    // каталог архива, опционально&lt;br /&gt;
    {&lt;br /&gt;
       ArchCatRecord    fileRecord; // запись о файле в каталоге архива&lt;br /&gt;
    } по количеству файлов в архиве;&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== FCU ===&lt;br /&gt;
Структура файла: нет начального заголовка, весь файл архива состоит из набора архивированных файлов:&lt;br /&gt;
заголовок + сжатый поток + контрольные суммы.&lt;br /&gt;
&lt;br /&gt;
Заголовок: 7 слов = 14 байт&lt;br /&gt;
* три слова: Имя + расширение файла в RADIX-50&lt;br /&gt;
* слово: Длина исходного файла, в блоках&lt;br /&gt;
* слово: Дата файла; старший бит означает что файл был защищён от записи (PROTECTED)&lt;br /&gt;
* два слова: Длина файла в архиве (с точностью до слова)&lt;br /&gt;
** Первое слово&lt;br /&gt;
*** младший байт это количество слов&lt;br /&gt;
*** старший байт это признак заголовка (0xBE = 0276 oct)&lt;br /&gt;
** Второе слово: количество блоков&lt;br /&gt;
&lt;br /&gt;
После заголовка следует собственно сжатый поток.&lt;br /&gt;
Длина этого блока в байтах определяется так:&lt;br /&gt;
(седьмое слово) * 512 + (младший байт 6-го слова) * 2&lt;br /&gt;
В эту длину входят также два слова контрольных сумм.&lt;br /&gt;
&lt;br /&gt;
В самом конце блока со сжатым потоком бит лежат два слова:&lt;br /&gt;
* предпоследнее слово: контрольная сумма исходного файла&lt;br /&gt;
* последнее слово: контрольная сумма сжатого потока&lt;br /&gt;
&lt;br /&gt;
Контрольная сумма считается простым сложением слов.&lt;br /&gt;
&lt;br /&gt;
Собственно сжатие выполняется алгоритмом Huffman, за основу была взята известная реализация lzhuf.c от Haruyasu Yoshizaki и Hurahiko Okumura.&lt;br /&gt;
Параметры алгоритма:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
// LZSS compression&lt;br /&gt;
&lt;br /&gt;
#define N               4096        // buffer size&lt;br /&gt;
#define F               60          // lookahead buffer size&lt;br /&gt;
#define THRESHOLD       2&lt;br /&gt;
const uint16_t NIL =    0xFFFE;    // leaf of tree&lt;br /&gt;
&lt;br /&gt;
// Huffman coding&lt;br /&gt;
&lt;br /&gt;
#define N_CHAR          (256 - THRESHOLD + F)&lt;br /&gt;
// kinds of characters (character code = 0..N_CHAR-1)&lt;br /&gt;
#define T               (N_CHAR * 2 - 1)        // size of table&lt;br /&gt;
#define R               (T - 1)     // position of root&lt;br /&gt;
#define MAX_FREQ        0x8000      // updates tree when the root frequency comes to this value.&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Существенное отличие от оригинала, это кодирование потока бит. В Huffman мы имеем дело с потоком бит, поэтому важно как они укладываются в байты и слова.&lt;br /&gt;
Обычно это просто &amp;quot;берём байты друг за другом&amp;quot; и для каждого байта либо &amp;quot;MSB first&amp;quot; (от старших бит к младшим) либо &amp;quot;LSB first&amp;quot; (от младших бит к старшим).&lt;br /&gt;
Но в FCU всё сложнее, потому что энкодер сохраняет словами, плюс little endian для байт в слове. Поэтому, получается так:&lt;br /&gt;
* во-первых, используем MSB, поэтому для слова `0xABCD` порядок выдачи бит в исходящем потоке будет &amp;lt;code&amp;gt;A B C D&amp;lt;/code&amp;gt;.&lt;br /&gt;
* во-вторых, little endian, поэтому в виде байт это сохраняется в порядке: &amp;lt;code&amp;gt;[CD] [AB]&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
[[Категория:УКНЦ]]&lt;/div&gt;</summary>
		<author><name>Nzeemin</name></author>
	</entry>
</feed>