렘펠-지브-마르코프 연쇄 알고리즘

Lempel–Ziv–Markov chain algorithm

LZMA(Lempel–Ziv–Markov chain algorithm)는 무손실 데이터 압축을 수행하는 데 사용되는 알고리즘입니다. 1996년 또는 1998년 Igor[1] Pavlov에 의해 개발되었으며 7-Zip 아카이브의 7z 형식으로 처음 사용되었습니다. 이 알고리즘은 1977년 Abraham LempelJacob Ziv가 발표한 LZ77 알고리즘과 다소 유사한 방식의 사전 압축 방식을 사용하며 높은 압축 비율(일반적으로 bzip2보다 높음)[2][3]과 가변적인 압축-사전 크기(최대 4GB)를 특징으로 합니다.[4] 일반적으로 사용되는 다른 압축 알고리즘과 유사한 압축 해제 속도를 유지합니다.[5]

LZMA2는 압축되지 않은 데이터와 LZMA 데이터를 모두 포함할 수 있는 간단한 컨테이너 형식으로, 여러 개의 다른 LZMA 인코딩 파라미터를 사용할 수 있습니다. LZMA2는 임의로 확장 가능한 다중 스레드 압축 및 압축 해제와 부분적으로 압축 불가능한 데이터의 효율적인 압축을 지원합니다.[6]

개요

LZMA는 사전 압축 알고리즘(거대한 사전 크기와 반복적으로 사용되는 일치 거리에 대한 특별한 지원을 가진 LZ77의 변형)을 사용합니다. 그런 다음 출력은 복잡한 모델을 사용하여 범위 인코더로 인코딩되어 각 비트의 확률 예측을 수행합니다. 사전 압축기는 정교한 사전 데이터 구조를 사용하여 일치하는 것을 찾고, 범위 인코더에 의해 한 번에 한 비트씩 인코딩되는 리터럴 심볼 및 구문 참조 스트림을 생성합니다. 많은 인코딩이 가능하며, 동적 프로그래밍 알고리즘을 사용하여 특정 근사치 하에서 최적의 것을 선택합니다.[7]

LZMA 이전의 대부분의 인코더 모델은 순수하게 바이트 기반이었습니다(즉, 동일한 바이트의 이전 비트에 대한 종속성을 나타내기 위해 캐스케이드 컨텍스트만을 사용하여 각 비트를 코딩했습니다). LZMA의 주요 혁신은 일반적인 바이트 기반 모델 대신 LZMA의 모델은 리터럴 또는 구의 각 표현의 비트 필드에 특정한 컨텍스트를 사용한다는 것입니다. 이는 일반적인 바이트 기반 모델처럼 거의 간단하지만 관련 없는 비트를 동일한 컨텍스트에서 함께 혼합하는 것을 피하기 때문에 훨씬 더 나은 압축을 제공합니다. 또한 고전적인 사전 압축(zipgzip 형식에 사용되는 것과 같은)과 비교할 때, 사전 크기는 현대 시스템에서 사용할 수 있는 많은 양의 메모리를 활용하여 훨씬 더 클 수도 있고 일반적으로 훨씬 더 클 수도 있습니다.[7]

압축 형식개요

LZMA 압축에서 압축된 스트림은 적응적 이진 범위 코더를 사용하여 인코딩된 비트 스트림입니다. 스트림은 패킷으로 나뉘는데, 각 패킷은 단일 바이트 또는 길이와 거리가 암시적 또는 명시적으로 인코딩된 LZ77 시퀀스를 기술합니다. 각 패킷의 각 부분은 독립적인 컨텍스트로 모델링되므로 각 비트에 대한 확률 예측은 동일한 유형의 이전 패킷의 해당 비트(및 동일한 필드의 관련 비트) 값과 상관됩니다. lzip[8] 및 LZMA SDK 설명서 모두 이 스트림 형식을 설명합니다.[7]

7가지 유형의 패킷이 있습니다.[8]

패킹된 코드(비트 시퀀스) 패킷명 패킷설명
0 + 바이트코드 불을 켰다. 적응형 이진 범위 코더를 사용하여 인코딩된 단일 바이트입니다.
1+0 + len + dist 경기 서열 길이와 거리를 설명하는 전형적인 LZ77 서열.
1+1+0+0 숏렙 1바이트 LZ77 시퀀스입니다. 거리는 마지막으로 사용한 LZ77 거리와 같습니다.
1+1+0+1+렌 LONG REP[0] LZ77 시퀀스입니다. 거리는 마지막으로 사용한 LZ77 거리와 같습니다.
1+1+1+0+렌 롱렙[1] LZ77 시퀀스입니다. 거리는 두 번째로 사용된 LZ77 거리와 같습니다.
1+1+1+1+0 + len 롱렙[2] LZ77 시퀀스입니다. 거리는 마지막으로 사용한 세 번째 LZ77 거리와 같습니다.
1+1+1+1+1 + len 롱렙[3] LZ77 시퀀스입니다. 거리는 마지막으로 사용한 네 번째 LZ77 거리와 같습니다.

LONG REP[*]는 LONG REP[0–3] 패킷을 의미하며, *REP는 LONG REP와 SHORT REP를 모두 의미하며, *MATCH는 MATCH와 *REP를 모두 의미합니다.

LONGREP[n] 패킷은 가장 최근 거리 목록에서 사용된 거리를 제거한 후 앞에 다시 삽입하여 불필요한 반복 항목을 방지하고, MATCH는 목록에 이미 존재하더라도 앞에 거리를 추가할 뿐이며 SHORTREP 및 LONGREP[0]은 목록을 변경하지 않습니다.

길이는 다음과 같이 인코딩됩니다.

길이코드(비트시퀀스) 묘사
0+3비트 3비트를 사용하여 인코딩된 길이는 2에서 9까지의 길이 범위를 제공합니다.
1+0+3비트 3비트를 사용하여 인코딩된 길이는 10에서 17 사이의 길이 범위를 제공합니다.
1+1+8비트 8비트를 사용하여 인코딩된 길이는 18에서 273 사이의 길이 범위를 제공합니다.

LZ77과 마찬가지로 길이는 거리의 제한을 받지 않습니다. 사전에서 복사하는 것은 바이트 단위로 복사를 수행한 것처럼 정의되어 거리를 일정하게 유지하기 때문입니다.

거리는 논리적으로 32비트이며, 가장 최근에 사전에 추가된 바이트까지의 거리는 0포인트입니다.

거리 부호화는 6비트 "거리 슬롯"으로 시작하며, 이는 몇 비트가 더 필요한지를 결정합니다. 다음 표에 따르면, 거리는 거리 슬롯에 따라 최대에서 최소까지 2비트, 고정된 0.5 확률로 인코딩된 일부 비트 및 일부 컨텍스트 인코딩된 비트의 이진 연결로 디코딩됩니다(거리 슬롯 0-3은 거리 0-3을 직접 인코딩함).

거리 부호화[7]
6비트 거리 슬롯 최고 2비트 고정된 0.5 확률 비트 컨텍스트 인코딩 비트
0 00 0 0
1 01 0 0
2 10 0 0
3 11 0 0
4 10 0 1
5 11 0 1
6 10 0 2
7 11 0 2
8 10 0 3
9 11 0 3
10 10 0 4
11 11 0 4
12 10 0 5
13 11 0 5
14–62 (이븐) 10 ((slot / 2) − 5) 4
15–63 (홀수) 11 ((slot - 1) / 2) - 5) 4

압축해제알고리즘내역

다음 텍스트에서 시도한 것 외에는 압축 형식의 완전한 자연어 사양이 존재하지 않는 것 같습니다.

아래 설명은 LZMA 및 LZMA2 알고리즘 세부 사항을 비교적 쉽게 추론할 수 있는 리눅스 커널 소스에[9] 포함된 Lasse Collin의 콤팩트 XZ Embedded 디코더를 기반으로 합니다. 따라서 소스 코드를 참조로 인용하는 것은 이상적이지 않지만 프로그래머라면 몇 시간의 작업으로 아래 클레임을 확인할 수 있어야 합니다.

비트의 범위 부호화

LZMA 데이터는 LZMA 디코더의 방향에서 범위 디코더에 의해 한 번에 한 비트씩 디코딩된 가장 낮은 레벨입니다.

컨텍스트 기반 범위 디코딩은 "컨텍스트"에 대한 참조를 통과시키는 LZMA 알고리즘에 의해 호출되며, 이는 비트의 예측된 확률을 나타내는 부호화되지 않은 11비트 가변 확률(일반적으로 16비트 데이터 유형을 사용하여 구현됨)로 구성됩니다. 범위 디코더에 의해 읽고 업데이트됩니다(0.5 확률을 나타내는 2로 초기화되어야 합니다).

고정 확률 범위 디코딩은 대신 0.5 확률을 가정하지만 컨텍스트 기반 범위 디코딩과는 약간 다르게 작동합니다.

범위 디코더 상태는 개의 부호화되지 않은 32비트 변수, 즉 범위(범위 크기를 나타냄) 및 코드(범위 내의 인코딩된 포인트를 나타냄)로 구성됩니다.

범위 디코더의 초기화는 범위32 2 - 1로 설정하고 big-endian으로 해석되는 스트림의 두 번째 바이트에서 시작하는 32비트 값에 대한 코드로 구성됩니다. 스트림의 첫 번째 바이트는 완전히 무시됩니다.

정규화는 다음과 같은 방식으로 진행됩니다.

  1. 범위코드를 모두 8비트씩 이동합니다.
  2. 압축된 스트림에서 바이트 읽기
  3. 최소 8비트의 코드를 바이트 값으로 설정합니다.

확률 변수를 사용한 비트의 컨텍스트 기반 범위 디코딩은 다음과 같은 방식으로 진행됩니다.

  1. 범위 미만인 경우 정규화를 수행합니다
  2. ⌋ × prob displaystyle \lfloor 범위/2^{11}\times prob}로 바인딩 설정
  3. 코드가 바운드 미만인 경우:
    1. 범위를 바인딩으로 설정
    2. prob + ⌊ 2 -⌋ / 25 2^{rfloor /2^{5}}로 설정합니다.
    3. 반환 비트 0
  4. 그렇지 않은 경우(코드경계보다 크거나 같은 경우):
    1. 범위범위로 설정 - 바운드
    2. 코드코드로 설정 - 바인딩
    3. 로 설정-/ ⌋ {\prob / 2^{5}\rffloor}
    4. 반환 비트 1

비트의 고정 확률 범위 디코딩은 다음과 같은 방식으로 진행됩니다.

  1. 범위 미만인 경우 정규화를 수행합니다
  2. ⌋로 설정 \ 범위/2\rfloor
  3. 코드범위 미만인 경우:
    1. 반환 비트 0
  4. 그렇지 않은 경우(코드범위보다 크거나 같을 경우):
    1. 코드코드로 설정 - 범위
    2. 반환 비트 1

고정 확률 디코딩의 리눅스 커널 구현은 rc_direct(), 성능상의 이유로 조건부 분기를 포함하지 않고 코드에서 범위를 무조건 빼줍니다. 결과적인 부호 비트는 반환할 비트를 결정하는 데 사용되고 코드와 결합되어 범위에 추가되는 마스크를 생성하는 데 사용됩니다.

참고:

  1. 로 나눗셈한 후가 아니라 곱셈 전에 바인딩 및 플로어 연산을 수행하는 경우(64비트 결과를 가진 32비트 곱셈에 대한 빠른 하드웨어 지원 필요성을 피하기 위한 것으로 보임)
  2. 고정 확률 디코딩은 어떤 확률 값을 갖는 컨텍스트 기반 범위 디코딩과 엄밀하게 동일하지 않은 반면, 컨텍스트 기반 범위 디코딩은 방금 설명된 것과 같이 확률을 곱하기 전에 하위 11 비트의 범위를 폐기하는 반면, 고정 확률 디코딩은 마지막 비트만을 폐기하는 것인 방법

정수의 범위 부호화

범위 디코더는 또한 위에서 설명한 단일 비트 디코딩을 일반화하고 정수를 디코딩하는 데 사용되는 비트 트리, 역 비트 트리 및 고정 확률 정수 디코딩 기능을 제공합니다. 부호 없는 정수를 한계 미만으로 디코딩하기 위해 (한계 - 1) 11비트 확률 변수 배열이 제공되며, 이들은 개념적으로 한계 잎이 있는 완전한 이진 트리의 내부 노드로 배열됩니다.

비역 비트 트리 디코딩은 변수 트리에 대한 포인터를 유지함으로써 작동하며, 이 포인터는 루트에서 시작됩니다. 포인터가 리프를 가리키지 않는 한, 포인터가 가리키는 변수를 사용하여 비트를 디코딩하고, 비트가 0인지 1인지에 따라 포인터가 왼쪽 또는 오른쪽 자식으로 이동되고, 포인터가 리프를 가리킬 때, 리프와 연관된 숫자가 반환되는 것을 특징으로 하는 방법.

따라서 비역 비트 트리 디코딩은 가장 중요한 비트에서 가장 중요하지 않은 비트로 발생하며, 유효한 범위 내의 하나의 값만 가능할 때 중단됩니다(LZMA가 이를 사용하지 않더라도 개념적으로 2의 거듭제곱이 아닌 범위 크기를 가질 수 있습니다).

역 비트 트리 디코딩은 대신 최소 유효 비트에서 최대 유효 비트로 디코딩하므로 2의 거듭제곱인 범위만 지원하며 항상 동일한 수의 비트를 디코딩합니다. 이는 2 제한의 전력으로 비역 비트 트리 디코딩을 수행하고 결과의 마지막 로그2(limit) 비트를 반전시키는 것과 같습니다.

에서 리눅스 커널에서 rc_bitree 함수는 실제로 [limit, 2 × limit] 범위에서 정수가 반환되며 (개념 값에 제한이 추가됨) 배열에서 인덱스 0의 변수는 사용되지 않는 반면 인덱스 1의 변수는 루트이며 왼쪽 및 오른쪽 자식 인덱스는 2i 및 2i + 1로 계산됩니다. 대신 rc_bitree_reverse 함수는 [0, limit] 범위의 정수를 호출자가 제공한 변수에 추가합니다. 여기서 한계는 로그로 암시적으로 표시되며 효율성 이유로 자체적으로 독립적으로 구현됩니다.

고정 확률 정수 디코딩은 단순히 고정 확률 비트 디코딩을 반복적으로 수행하여 비트를 최대에서 최소로 읽습니다.

LZMA 구성

LZMA 디코더는 lclppb "속성" 바이트와 사전 크기로 구성됩니다. lclppb 바이트의 값은 lc + lp × 9 + pb × 9 × 5입니다. 여기서:

  • lc는 리터럴 인코딩을 위한 컨텍스트로 사용할 이전 바이트의 높은 비트 수입니다(LZMA SDK에서 사용되는 기본값은 3).
  • lpliteral_pos_state에 포함할 사전 위치의 낮은 비트 수입니다(LZMA SDK에서 사용하는 기본값은 0).
  • pbpos_state에 포함할 사전 위치의 낮은 비트 수입니다(LZMA SDK에서 사용하는 기본값은 2).

LZMA2가 아닌 스트림에서는 lc가 8을 초과해서는 안 되며 lp와 pb는 4를 초과해서는 안 됩니다. LZMA2 스트림에서 (lc + lp)pb는 4를 초과해서는 안 됩니다.

7-zip LZMA 파일 형식에서 구성은 "속성" 바이트를 포함하는 헤더와 32비트 리틀 엔디안 사전 크기(바이트)에 의해 수행됩니다. LZMA2에서는 LZMA2 LZMA 패킷 시작 시 속성 바이트를 선택적으로 변경할 수 있지만, 사전 크기는 나중에 설명한 대로 LZMA2 헤더에 지정됩니다.

LZMA 코딩 컨텍스트

LZMA 패킷 형식은 이미 설명되어 있으며, 이 섹션에서는 LZMA가 LZ 인코딩된 스트림을 통계적으로 모델링하는 방법, 즉 각 비트를 디코딩하기 위해 범위 디코더에 전달되는 확률 변수를 지정합니다.

이러한 확률 변수는 다차원 배열로 구현되며, 이를 도입하기 전에 이러한 다차원 배열에서 인덱스로 사용되는 몇 가지 값을 정의합니다.

상기 상태값은 개념적으로 하기 표의 패턴들 중 어느 것이 가장 최근에 본 2-4개의 패킷 타입과 일치하는지를 기준으로 하며, 패킷이 출력될 때마다 표에 기재된 전이 테이블에 따라 업데이트되는 상태 머신 상태로 구현되는 것을 특징으로 하는 방법.

초기 상태는 0이므로 시작 전 패킷은 LIT 패킷으로 가정됩니다.

이전 패킷 다음 패킷이 있을 때 다음 상태
전4위 전3위 전2위 이전의 불을 켰다. 경기 LONG REP[*] 숏렙
0 불을 켰다. 불을 켰다. 불을 켰다. 0 7 8 9
1 경기 불을 켰다. 불을 켰다. 0 7 8 9
2 LONG REP[*] 불을 켰다. 불을 켰다. 0 7 8 9
*MATCH 숏렙
3 불을 켰다. 숏렙 불을 켰다. 불을 켰다. 0 7 8 9
4 경기 불을 켰다. 1 7 8 9
5 LONG REP[*] 불을 켰다. 2 7 8 9
*MATCH 숏렙
6 불을 켰다. 숏렙 불을 켰다. 3 7 8 9
7 불을 켰다. 경기 4 10 11 11
8 불을 켰다. LONG REP[*] 5 10 11 11
9 불을 켰다. 숏렙 6 10 11 11
10 *MATCH 경기 4 10 11 11
11 *MATCH *REP 5 10 11 11

pos_stateliteral_pos_state 값은 각각 사전 위치의 최소 비트(최대 4개, LZMA 헤더 또는 LZMA2 속성 패킷에서 사전 크기로 재설정된 마지막 이후 코딩된 바이트 수)로 구성됩니다. 사전 크기는 일반적으로 2의 큰 거듭제곱의 배수이므로 이 값들은 마지막 사전 재설정 이후 압축되지 않은 바이트 수의 가장 중요하지 않은 비트로 동등하게 설명됩니다.

prev_byte_lc_msbs 값은 이전 비압축 바이트의 가장 중요한 비트인 lc(LZMA 헤더 또는 LZMA2 속성 패킷에서 최대 4개)로 설정됩니다.

is_REP 값은 길이를 포함하는 패킷이 MATCH가 아닌 LONG REP인지를 나타냅니다.

match_byte 값은 SHORTREP 패킷이 사용되었다면 디코딩되었을 바이트(즉, 마지막으로 사용된 거리의 사전에서 발견된 바이트)이며 *MATCH 패킷 바로 뒤에만 사용됩니다.

literal_bit_mode는 0~2 범위의 8개 값의 배열로, 이전 패킷이 *MATCH이고 가장 중요한 비트 위치이거나 리터럴에서 인코딩/디코딩할 모든 더 중요한 비트가 match_byte의 해당 위치에 있는 비트와 동일한 경우 1 또는 2입니다. 그렇지 않으면 0이지만 1 또는 2 값 중 하나의 선택은 match_byte의 동일한 위치에 있는 비트의 값에 따라 달라집니다.

리터럴/리터럴 변수 집합은 비트 트리와 유사하지만 모든 노드에 1개가 아닌 3개의 변수가 있는 "pseudo-bit-tree"로 볼 수 있으며, 노드에서 표시된 비트 트리 컨텍스트 뒤에 디코딩할 다음 비트의 비트 위치에서 리터럴_bit_mode 값에 따라 선택됩니다.

일부 소스에서는 *MATCH 뒤에 리터럴이 match_byte와 함께 바이트 값의 XOR로 코딩되는 것이 잘못되었다는 주장이 발견됩니다. 대신 단순히 바이트 값으로 코딩되지만 방금 설명한 의사 비트 트리와 아래 표에 나열된 추가 컨텍스트를 사용합니다.

LZMA에서 사용되는 확률 변수 그룹은 다음과 같습니다.

XZ이름 LZMA SDK 이름 매개변수화: 사용할 때 코딩모드 비트 0이면. 비트 1이면.
is_match IsMatch state, pos_state 패킷 시작 조금 불을 켰다. *MATCH
is_rep IsRep 비트 수열 1 다음에 조금 경기 *REP
is_rep0 IsRepG0 비트 수열 11 다음에 조금 SHORTREP/

LONG REP[0]

롱렙[1~3]
is_rep0_long IsRep0Long state, pos_state 비트 수열 110 이후 조금 숏렙 LONG REP[0]
is_rep1 IsRepG1 비트 수열 111 다음에 조금 롱렙[1] 롱렙[2/3]
is_rep2 IsRepG2 비트 시퀀스 후 1111 조금 롱렙[2] 롱렙[3]
문자 그대로의 문자 그대로 prev_byte_lc_msbs, 리터럴_pos_state, 리터럴_bit_mode[비트 위치], 비트 트리 컨텍스트 비트 시퀀스 0 뒤에 256개의 값 의사 비트 트리 리터럴 바이트 값
dist_ 포스슬롯 min(match_length, 5), 비트 트리 컨텍스트 거리: 시작 64 값 비트 트리 거리 슬롯
dist_특별한 스펙포스 distance_slot, 리버스 비트 트리 컨텍스트 거리 : 4~13개의 거리 슬롯 ((distance_slot>> 1) - 1) 비트 역 비트 트리 낮은 거리
dist_ 정렬 역 비트 트리 컨텍스트 거리: 14개 이상의 거리 슬롯, 고정 확률 비트 후 4비트 리버스 비트 트리 낮은 거리
len_dec.선택 렌초이스 is_REP 매치 길이 : 시작 조금 길이 2~9 10+ 길이
len_dec.선택2 렌초이스2 is_REP 일치 길이: 비트 시퀀스 1 이후 조금 10-17 길이 18+ 길이
len_dec.low 렌 로우 is_REP, pos_state, 비트 트리 컨텍스트 일치 길이: 비트 시퀀스 0 이후 8개의 값 비트 트리 짧은 길이의 작은 조각들
len_dec.mid 렌미드 is_REP, pos_state, 비트 트리 컨텍스트 일치 길이: 비트 시퀀스 후 10 8개의 값 비트 트리 중간 정도의 길이
len_dec의높은 렌하이 is_REP, 비트 트리 컨텍스트 일치 길이: 비트 시퀀스 후 11 256개의 값 비트 트리 높은 길이의 비트들

LZMA2 format

LZMA2 컨테이너는 압축된 LZMA 데이터와 압축되지 않은 데이터의 여러 실행을 지원합니다. 각 LZMA 압축 실행은 서로 다른 LZMA 구성 및 사전을 가질 수 있습니다. 이를 통해 부분적으로 또는 완전히 압축 불가능한 파일의 압축이 향상되고 병렬로 독립적으로 압축 또는 압축 해제할 수 있는 실행으로 파일을 분할하여 다중 스레드 압축 및 다중 스레드 압축 해제가 가능합니다. LZMA에 대한 LZMA2의 변화에 대한 비판에는 CRC에 의해 커버되지 않는 헤더 필드와 실제로는 병렬 압축 해제가 불가능한 것이 포함됩니다.[6]

LZMA2 헤더는 사전 크기를 나타내는 바이트로 구성됩니다.

  • 40은 4GB - 1 사전 크기를 나타냅니다.
  • 값이 40 미만인 경우에도 사전 크기가 2바이트임을v/2 + 12 나타냅니다.
  • 홀수 값이 40보다 작으면 3×2바이트(v − 1)/2 + 11 사전 크기를 나타냅니다.
  • 40보다 큰 값이 잘못되었습니다.

LZMA2 데이터는 제어 바이트로 시작하는 패킷으로 구성되며 다음 값이 있습니다.

  • 0은 파일의 끝을 나타냅니다.
  • 1은 사전 재설정 후 압축되지 않은 청크를 의미합니다.
  • 2는 사전 리셋 없이 압축되지 않은 청크를 나타냅니다.
  • 3 - 0x7f는 유효하지 않은 값입니다.
  • 0x80–0xff는 LZMA 청크를 의미하며, 가장 낮은 5비트는 압축되지 않은 크기의 비트 16–20으로 사용되며, 비트 5–6은 재설정해야 할 것을 나타냅니다.

LZMA 청크의 비트 5 ~ 6은 다음과 같습니다.

  • 0: 재설정 안 함
  • 1: 상태 재설정
  • 2: 상태 재설정, 속성 바이트를 사용하여 속성 재설정
  • 3: 상태 재설정, 속성 바이트를 사용한 속성 재설정, 사전 재설정

LZMA 상태 재설정은 사전을 제외한 모든 LZMA 상태를 재설정하게 하며, 구체적으로는 다음과 같습니다.

  • 레인지 코더
  • 상태값
  • 반복되는 경기의 마지막 거리
  • 모든 LZMA 확률

압축되지 않은 청크는 다음과 같이 구성됩니다.

  • 데이터 크기에서 1을 뺀 16비트 빅 엔디안 값
  • 사전 및 출력으로 복사할 데이터

LZMA 청크는 다음과 같이 구성됩니다.

  • 압축되지 않은 크기에서 1을 뺀 16비트의 낮은 16비트를 인코딩하는 16비트 빅 엔디안 값
  • 압축된 크기를 인코딩하는 16비트 빅 엔디안 값에서 1을 뺀 값
  • 제어 바이트의 비트 6이 설정된 경우 속성/lclppb 바이트
  • 범위 코더를 초기화하는 데 사용되는 5바이트(첫 번째 바이트는 무시됨)부터 시작하는 LZMA 압축 데이터(압축된 크기에 포함됨)

xz 및 7z 형식

LZMA2 데이터를 포함할 수 있는 .xz 형식은 tukaani.org 에 문서화되어 있으며, LZMA 또는 LZMA2 데이터를 포함할 수 있는 .7z 파일 형식은 7z 형식으로 문서화되어 있습니다.LZMA SDK에 포함된 txt 파일입니다.[11]

압축알고리즘상세

압축 해제 형식 상황과 마찬가지로 7-zip 또는 xz의 인코딩 기법에 대한 완전한 자연어 사양은 다음 텍스트에서 시도되는 것 외에는 존재하지 않는 것으로 보입니다.

아래 설명은 Lasse Collin의 자바 인코더용 XZ를 기반으로 하며,[12] 이는 동일한 알고리즘을 사용하여 원본 7-zip을 다시 쓴 여러 번 중 가장 읽기 쉬운 것으로 보입니다. 다시 말하지만, 소스 코드를 참조로 인용하는 것은 이상적이지 않지만, 프로그래머라면 누구나 몇 시간의 작업으로 아래의 클레임을 확인할 수 있어야 합니다.

레인지 인코더

범위 인코더는 흥미로운 선택을 할 수 없으며 디코더 설명을 기반으로 쉽게 구성할 수 있습니다.

초기화 및 종료는 완전히 결정되지 않았습니다. xz 인코더는 압축 해제기에서 무시되는 첫 번째 바이트로 0을 출력하고 (최종 바이트에 중요한) 범위의 하한을 인코딩합니다.

xz 인코더는 low(일반적으로 64비트 정수로 구현됨, 0으로 초기화됨)라고 하는 부호 없는 33비트 변수, 범위라고32 하는 부호 없는 32비트 변수, 캐시라고 하는 부호 없는 8비트 변수(0으로 초기화됨)를 사용합니다. 압축되지 않은 크기를 저장할 수 있을 만큼 커야 하는 cache_size라는 부호 없는 변수(일반적으로 64비트 정수로 구현됨)도 있습니다.

캐시/cache_size 변수는 캐리를 적절하게 처리하는 데 사용되며 캐시 값으로 시작하는 빅 엔디안 시퀀스로 정의된 숫자를 나타내고 캐시_size 0xff 바이트가 뒤따릅니다. 캐시 크기 0xff 바이트는 낮은 레지스터에서 이동되었지만 캐리로 인해 하나씩 증가할 수 있기 때문에 아직 기록되지 않았습니다.

캐시로우는 0으로 초기화되고 인코더 구현은 xz 디코더가 이 바이트를 무시하기 때문에 첫 번째 바이트 출력은 항상 0이 됩니다.

정규화는 다음과 같은 방식으로 진행됩니다.

  1. 낮음이 (- 2 미만인 경우:
    1. 캐시에 저장된 바이트를 압축된 스트림으로 출력
    2. 출력 cache_size - 0xff 값을 가진 1바이트
    3. 캐시를 비트 24~31로 낮게 설정
    4. cache_size를 0으로 설정
  2. 낮음 2보다 크거나 같으면
    1. 캐시에 저장된 바이트와 압축된 스트림에 하나를 더한 바이트 출력
    2. 출력 cache_size - 값이 0인 1바이트
    3. 캐시를 비트 24~31로 낮게 설정
    4. cache_size를 0으로 설정
  3. 증분 캐시_size
  4. 8비트씩 로우 시프트된 왼쪽의 최저 24비트로 로우 설정
  5. 범위를 8비트 왼쪽으로 이동하여 범위로 설정

확률 변수를 사용한 비트의 컨텍스트 기반 범위 인코딩은 다음과 같은 방식으로 진행됩니다.

  1. 범위 미만인 경우 정규화를 수행합니다
  2. ⌋ × prob displaystyle \lfloor 범위/2^{11}\times prob}로 바인딩 설정
  3. 0비트를 인코딩하는 경우:
    1. 범위를 바인딩으로 설정
    2. prob+ ⌊ 2 - ⌋ / 2^{rfloor /2^{5}}로 설정
  4. 그렇지 않은 경우(1비트를 인코딩하는 경우):
    1. 범위범위로 설정 - 바운드
    2. low에서 low + bound로 설정
    3. 로 설정-/ ⌋ {\prob / 2^{5}\rffloor}

비트의 고정 확률 범위 인코딩은 다음과 같은 방식으로 진행됩니다.

  1. 범위 미만인 경우 정규화를 수행합니다
  2. ⌋로 설정 \ 범위/2\rfloor
  3. 1비트를 인코딩하는 경우:
    1. low ~ low + range로 설정

종료는 다음과 같은 방법으로 진행됩니다.

  1. 정규화 5회 수행

비트 트리 인코딩은 비트 디코딩 함수들의 결과로부터가 아니라 인코딩될 입력 정수로부터 비트 값들을 가져온다는 것을 제외하고는 디코딩과 같이 수행됩니다.

가장 짧은 범위의 인코딩 크기로 인코딩을 계산하려는 알고리즘의 경우 인코더는 또한 그 추정치를 제공해야 합니다.

사전 검색 데이터 구조

인코더는 사전에서 일치하는 항목을 빠르게 찾을 수 있어야 합니다. LZMA는 압축을 향상시키기 위해 매우 큰 사전을 사용하기 때문에 (아마도 기가바이트 정도의) 전체 사전을 스캔하기만 하면 인코더가 너무 느려서 실질적으로 사용할 수 없기 때문에 빠른 일치 검색을 지원하기 위해서는 정교한 데이터 구조가 필요합니다.

해시 체인

"해시 체인"이라고 불리는 가장 간단한 접근 방식은 2, 3 또는 4 중 하나가 될 수 있는 상수 N으로 매개변수화되며, 일반적으로 2가N 사전 크기 이상이 되도록 선택됩니다.

N보다 작거나 같은 각 k대해 k 바이트의 튜플로 인덱싱된 해시 테이블을 생성하는 것으로 구성되며, 각 버킷은 해당 해시 테이블 버킷과 관련된 해시 값에 첫 번째 k 바이트가 해시된 마지막 위치를 포함합니다.

모든 사전 위치에 대해 첫 번째 N바이트가 해당 위치의 첫 번째 N바이트와 동일한 값으로 해시되는 마지막으로 보이는 이전 위치를 저장하는 추가 어레이에 의해 체인링이 달성됩니다.

길이가 N 이상인 일치 항목을 찾기 위해 N-사이즈 해시 테이블을 사용하여 검색을 시작하고 해시 체인 배열을 계속 사용합니다. 미리 정의된 수의 해시 체인 노드가 통과한 후 또는 해시 체인이 "랩"되면 검색을 중지합니다. 사전에 덮어쓴 입력 부분에 도달했음을 나타냅니다.

크기가 N보다 작은 일치는 해당 해시 테이블을 보기만 하면 찾을 수 있습니다. 해시 테이블에는 최신 일치 항목이 있거나 동일한 값으로 해시되는 문자열이 포함되어 있습니다. 후자의 경우 인코더가 일치 항목을 찾을 수 없습니다. 이 문제는 여러 리터럴을 사용하는 원거리 쇼트 매치의 경우 비트가 더 적게 필요할 수 있고, 근처 문자열에서 해시 충돌이 발생할 가능성이 상대적으로 낮다는 사실에 의해 완화됩니다. 더 큰 해시 테이블 또는 직접 조회 테이블을 사용하면 캐시 미스율이 더 높아져서 성능이 더 낮아질 수 있습니다.

해시 메커니즘은 과거 어느 시점에 해시 테이블 버킷 인덱스에 문자 해시가 있었다는 것만을 보장하기 때문에 모든 일치는 해당 사전 위치에서 실제 바이트가 현재 일치하는지 확인하기 위해 검증되어야 합니다. 데이터 구조를 초기화하지 않기 때문입니다.

LZMA는 이름에 "M"이 암시하는 대로 마르코프 체인을 사용합니다.

이진 트리

이진 트리 접근 방식은 해시 체인 접근 방식을 따르지만 논리적으로 연결된 목록 대신 이진 트리를 사용합니다.

이진 트리는 접미사 사전 순서에 상대적인 검색 트리와 사전 위치에[13] 대한 최대 힙(즉, 루트는 항상 가장 최근의 문자열이며 하위 문자열은 상위 문자열보다 더 최근에 추가할 수 없음)이 되도록 유지됩니다. 모든 문자열이 사전 순서로 정렬된다고 가정할 때, 이러한 조건은 이진 트리를 명확하게 고유하게 결정합니다(이것은 트리의 크기에 대한 귀납법에 의해 아주 작게 증명될 수 있습니다).

검색할 문자열과 삽입할 문자열이 동일하므로 사전 검색과 삽입(트리를 회전해야 함)을 하나의 트리 순회에서 모두 수행할 수 있습니다.

패트리샤는 노력합니다.

일부 오래된 LZMA 인코더는 Patricia tries를 기반으로 한 데이터 구조를 지원하기도 했지만, 이후 다른 옵션에 비해 성능이 떨어지는 것으로 판단되어 지원이 중단되었습니다.[13]

LZMA 인코더

LZMA 인코더는 출력할 일치 항목을 자유롭게 결정하거나 일치 항목의 존재를 무시하고 리터럴을 출력할 것인지 여부를 결정할 수 있습니다.

가장 최근에 사용된 4개의 거리를 불러올 수 있다는 것은, 원칙적으로 나중에 다시 필요한 거리와의 일치를 사용하는 것이 로컬 최적이 아니더라도 전역적으로 최적일 수 있다는 것을 의미하며, 그 결과, 최적의 LZMA 압축은 아마도 전체 입력에 대한 지식을 필요로 하며 실제로 사용하기에는 너무 느린 알고리즘을 필요로 할 수 있습니다.

이 때문에 실제 구현은 비글로벌 휴리스틱을 사용하는 경향이 있습니다.

xz 인코더는 nice_len(기본값은 64)이라는 값을 사용합니다. 적어도 nice_len 길이의 일치하는 것이 발견되면 인코더는 검색을 중지하고 최대 일치하는 길이로 출력합니다.

고속 인코더

XZ 고속 인코더[14](7-zip 고속 인코더에서 파생됨)는 xz 소스 트리에서 가장 짧은 LZMA 인코더입니다.

다음과 같이 작동합니다.

  1. 사전 데이터 구조에서 통합 검색 및 삽입 수행
  2. 반복되는 거리가 적어도 nice_len의 길이와 일치하는 경우:
    • REP 패킷으로 가장 자주 사용되는 거리 출력
  3. 적어도 nice_len 길이의 일치가 발견된 경우:
    • MATCH 패킷으로 출력
  4. 메인 매치를 가장 긴 매치로 설정합니다.
  5. 감소하는 길이 순서로 모든 길이의 가장 가까운 일치를 보고 교체할 수 없을 때까지 확인합니다.
    • 주 매치를 현재 주 매치 거리의 1/128보다 짧은 한 문자의 매치로 대체합니다.
  6. 현재 메인 매치 길이가 길이 2이고 거리가 128 이상인 경우 메인 매치 길이를 1로 설정합니다.
  7. 반복되는 매치가 발견되었으며, 메인 매치보다 최대 1자 정도 짧은 경우:
    • 반복되는 일치를 REP 패킷으로 출력
  8. 반복되는 매치가 발견되었으며, 메인 매치보다 최대 2자 정도 짧으며, 메인 매치 거리가 512 이상인 경우:
    • 반복되는 일치를 REP 패킷으로 출력
  9. 반복되는 매치가 발견되었고, 메인 매치보다 최대 3자 정도 짧으며, 메인 매치 거리가 32768 이상인 경우:
    • 반복되는 일치를 REP 패킷으로 출력
  10. 주 일치 크기가 2보다 작거나 일치하는 항목이 없는 경우:
    • LIT 패킷 출력
  11. 다음 바이트에 대한 사전 검색 수행
  12. 다음 바이트가 주 매치보다 최대 1자 정도 짧거나 거리가 주 매치 거리의 1/128배 미만이고 주 매치 길이가 3 이상인 경우:
    • LIT 패킷 출력
  13. 다음 바이트에 적어도 주 일치만큼 길고 주 일치보다 적은 거리가 일치하는 경우:
    • LIT 패킷 출력
  14. 다음 바이트에 기본 일치보다 한 문자 이상 긴 일치가 있고 거리의 1/128이 기본 일치 거리보다 작거나 같을 경우:
    • LIT 패킷 출력
  15. 다음 바이트에 기본 일치보다 두 문자 이상 긴 일치가 있는 경우:
    • LIT 패킷 출력
  16. 반복되는 매치가 메인 매치보다 최대 1자 정도 짧은 경우:
    • REP 패킷으로 가장 자주 사용되는 거리 출력
  17. MATCH 패킷으로 주 일치 출력

노멀 인코더

XZ 노멀 인코더[15](7-zip 노멀 인코더에서 파생된)는 xz 소스 트리의 다른 LZMA 인코더로, 생성된 패킷의 범위 인코딩 후 크기를 최소화하려는 보다 정교한 접근 방식을 채택합니다.

특히, 동적 프로그래밍 알고리즘의 결과를 사용하여 입력의 일부를 인코딩합니다. 여기서 하위 문제는 압축되는 바이트에서 시작하는 길이 L의 하위 문자열의 대략적인 최적 인코딩(범위 후 인코딩 크기가 최소인 인코딩)을 찾는 것입니다.

동적 프로그래밍 알고리즘에서 처리되는 입력 부분의 크기는 시작 위치(최대 LZMA 일치 길이, 273에 의해 캡핑됨)에서 발견되는 가장 긴 사전 일치와 가장 긴 반복 일치 사이의 최대치로 결정되고; 또한, 방금 정의된 범위의 임의의 지점에서 nice_len보다 긴 일치가 발견되면 동적 프로그래밍 알고리즘이 중지되고 해당 지점까지의 하위 문제에 대한 해결책이 출력되고 nice_len 크기의 일치가 출력되며 일치가 출력된 후 바이트에서 새로운 동적 프로그래밍 문제 인스턴스가 시작됩니다.

하위 문제 후보 솔루션은 후보 인코딩으로 점진적으로 업데이트되고, 길이 L'의 더 짧은 부분 문자열에 대한 솔루션을 사용하여 구성되며, 가능한 모든 "꼬리"로 확장되거나, L' 위치에서 입력을 인코딩하는 특정 제약 조건을 가진 1-3 패킷 세트입니다. 하위 문제의 최종 해결책이 발견되면 LZMA 상태와 그에 가장 적게 사용된 거리를 계산한 다음 확장의 범위 인코딩 후 크기를 적절하게 계산하는 데 사용됩니다.

동적 프로그래밍 최적화가 끝나면 고려된 가장 긴 부분 문자열의 전체 최적 인코딩이 출력되고 LZMA 상태 및 최소 사용 거리를 업데이트한 후 인코딩이 아직 인코딩되지 않은 첫 번째 비압축 바이트에서 인코딩이 계속됩니다.

각 하위 문제는 다음 패턴 중 하나와 일치해야 하는 "꼬리"라고 하는 패킷 시퀀스에 의해 확장됩니다.

첫번째 패킷 두번째 패킷 세번째 패킷
조금도
불을 켰다. LONG REP[0]
*MATCH 불을 켰다. LONG REP[0]

단일 패킷으로 확장할 뿐만 아니라 하위 문제는 성능 및 알고리즘 복잡성의 이유로 부분 문자열 길이만 매개 변수로 사용하고 최적의 동적 프로그래밍 접근 방식은 마지막 사용 거리와 LZMA 상태를 매개 변수로 사용해야 하기 때문입니다. 따라서, 여러 패킷으로 확장하면 최적의 솔루션을 더 잘 근사할 수 있으며, 특히 LONGREP[0] 패킷을 더 잘 사용할 수 있습니다.

각 하위 문제에 대해 다음 데이터가 저장됩니다(물론 저장된 값은 최소 가격의 후보 솔루션에 대한 것입니다). 여기서 "꼬리"는 더 작은 하위 문제의 솔루션을 확장하는 패킷을 의미하며, 이는 다음 구조에서 직접 설명됩니다.

Java용 XZ 멤버 이름 묘사
가격. 최소화할 수량: 문자열을 인코딩하는 데 필요한 범위 후 encoding 비트 수
optPrev 마지막 패킷을 제외한 모든 패킷으로 인코딩된 하위 문자열의 압축되지 않은 크기
백프리브 마지막 패킷이 LIT인 경우 -1, 마지막으로 사용한 거리 번호 0~3을 사용한 반복일 경우 0~3, MATCH인 경우 4 + 거리(prev1IsLiteral이 참일 경우 마지막 패킷은 LONGREP[0]만 사용할 수 있으므로 항상 0입니다.)
prev1Is Literal "꼬리"에 두 개 이상의 패킷이 포함된 경우 true입니다(이 경우 마지막 앞의 패킷은 LIT입니다).
Prev2가 있습니다. "꼬리"에 3개의 패킷이 포함된 경우 true입니다(prev1IsLiteral이 true인 경우에만 유효).
optPrev2 "꼬리"를 제외한 모든 패킷으로 인코딩된 하위 문자열의 압축되지 않은 크기(prev1IsLiteral이고 Prev2가 참인 경우에만 유효)
백 Prev2 "꼬리"의 첫 번째 패킷이 LIT인 경우 -1, 마지막으로 사용한 거리 번호 0~3을 사용한 반복일 경우 0~3, MATCH인 경우 4 + 거리(prev1IsLiteral이고 Prev2가 참일 경우에만 유효)
의원[4] 솔루션의 패킷 이후 마지막으로 사용된 4개 거리의 값(최상의 하위 문제 솔루션이 결정된 후에만 computed)
솔루션의 패킷 후 LZMA 상태 값(최상의 하위 문제 솔루션이 결정된 후에만 계산됨)

Java용 XZ 구현에서 optPrevbackPrev 멤버는 최종 솔루션 출력의 일부로 단일 링크 패킷 목록을 저장하는 데 재사용됩니다.

LZMA2 인코더

XZ LZMA2 인코더는 입력을 청크(최대 2MB의 비압축 크기 또는 64KB의 압축 크기 중 낮은 것)로 처리하여 각 청크를 LZMA 인코더에 전달한 다음, 인코딩된 데이터를 포함하는 LZMA2 LZMA 청크를 출력할지 또는 어느 것이 더 짧은지에 따라 LZMA2 비압축 청크를 출력할지를 결정합니다(LZMA, 다른 압축기와 마찬가지로, 어떤 종류의 데이터를 압축하는 것이 아니라 반드시 확장됩니다).

LZMA 상태는 호출자가 속성 변경을 요청하는 경우, 그리고 압축된 청크가 출력될 때마다 첫 번째 블록에서만 재설정됩니다. LZMA 속성은 첫 번째 블록에서만 변경되거나 호출자가 속성 변경을 요청하는 경우에만 변경됩니다. 사전은 첫 번째 블록에서만 재설정됩니다.

상위 인코딩 계층

LZMA2 인코딩 전에 제공되는 옵션에 따라 xz는 상대 오프셋을 더 반복적인 절대 오프셋으로 대체하도록 실행 가능한 코드를 필터링하는 BCJ 필터 또는 각 바이트를 해당 바이트와 바이트 간의 차이로 대체하는 델타 필터를 적용할 수 있습니다. N 앞에 바이트가 있습니다.

병렬 인코딩은 파일을 스레드에 배포되는 청크로 분할하여 수행되며, 궁극적으로 각각의 인코딩(예: xz 블록 인코딩 사용)이 별도로 수행되어 출력 파일의 청크 간 사전 리셋이 발생합니다.

7-Zip 참조 구현

7-Zip에서 추출한 LZMA 구현은 LZMA SDK로 이용할 수 있습니다. 원래는 GNU LGPL과 공통 공중 사용 허가서에 따라 이중 라이선스가 [16]되어 있었지만, 2008년 12월 2일 버전 4.62가 출시되면서 이고르 파블로프에 의해 퍼블릭 도메인에 배치되었습니다.[11]

LZMA의 개선된 버전인 [17]LZMA2 압축은 2012년 10월 26일 버전 9.30을 시작으로 이제 .7z 형식의 기본 압축 방법이 되었습니다.[18]

참조 오픈 소스 LZMA 압축 라이브러리는 원래 C++로 작성되었지만 ANSIC, C# Java로 포팅되었습니다.[11] 또한 C++ 라이브러리를 위한 타사 파이썬 바인딩과 LZMA에서 Pascal, GoAda까지의 포트도 있습니다.[19][20][21][22]

7-Zip 구현은 해시 체인, 이진 트리Patricia 트리의 여러 변형을 사전 검색 알고리즘의 기초로 사용합니다.

LZMA 외에도 SDK와 7-Zip은 단순한 델타 인코딩(이미지용)과 실행 코드용 BCJ에 이르기까지 압축을 개선하기 위한 여러 개의 전처리 필터를 구현합니다. 또한 7z에 사용되는 몇 가지 다른 압축 알고리즘을 제공합니다.

LZMA에 대한 압축 해제 전용 코드는 일반적으로 약 5KB로 컴파일되며, 압축 중에 필요한 RAM의 양은 주로 압축 중에 사용되는 슬라이딩 윈도우의 크기에 따라 결정됩니다. 작은 코드 크기와 상대적으로 낮은 메모리 오버헤드, 특히 더 작은 사전 길이, 자유 소스 코드는 LZMA 압축 해제 알고리즘을 임베디드 애플리케이션에 적합하게 만듭니다.

기타 구현

7-Zip 참조 구현 외에도 다음은 LZMA 형식을 지원합니다.

  • xz: xz 파일 형식으로 LZMA와 LZMA2를 모두 지원하는 gzip과 같은 명령줄 도구를 포함하는 스트리밍 구현. 고성능(bzip2에 비해)과 작은 크기(gzip에 비해)로 유닉스 계열의 여러 소프트웨어에 진출했습니다.[2] 리눅스 커널, dpkgRPM 시스템에는 xz 코드가 포함되어 있으며 kernel.org , 데비안 및 페도라와 같은 많은 소프트웨어 배포자들은 현재 릴리스를 압축할 때 xz를 사용합니다.
  • lzip: 대부분 유닉스 계열 시스템이 xz와 직접 경쟁할 수 있는 또 다른 LZMA 구현입니다.[24] 주로 파일 형식이 단순하여 오류 복구가 용이한 것이 특징입니다.
  • ZIPX: 버전 12.1부터 WinZip에서 만든 ZIP 압축 형식의 확장입니다. 또한 BZip, PPMd 등 다양한 다른 압축 방법을 사용할 수 있습니다.[25]

LZHAM

LZHAM(LZ, Huffman, Armetic, Markov)은 압축 처리량을 매우 높은 비율과 더 높은 압축 해제 처리량으로 거래하는 LZMA 유사 구현입니다. 2020년 9월 15일 저자에 의해 퍼블릭 도메인에 배치되었습니다.[26]

참고문헌

  1. ^ Igor Pavlov has asserted multiple times on SourceForge that the algorithm is his own creation. (2004-02-19). "LZMA spec?". Archived from the original on 2012-11-09. Retrieved 2013-06-16.
  2. ^ a b - Lasse Collin (2005-05-31). "A Quick Benchmark: Gzip vs. Bzip2 vs. LZMA". Retrieved 2015-10-21. LZMA 유닉스 포트는 마침내 더 나은 그리고 더 빠른 압축을 특징으로 하는 xz로 대체되었습니다. 여기서 우리는 심지어 LZMA 유닉스 포트가 gzip과 bzip2보다 훨씬 더 낫다는 것을 알게 되었습니다.
  3. ^ Klausmann, Tobias (2008-05-08). "Gzip, Bzip2 and Lzma compared". Blog of an Alpha animal. Archived from the original on 2013-01-06. Retrieved 2013-06-16.
  4. ^ Igor Pavlov (2013). "7z Format". Retrieved 2013-06-16.
  5. ^ Mahoney, Matt. "Data Compression Explained". Retrieved 2013-11-13.
  6. ^ a b Antonio Diaz Diaz. "Xz format inadequate for long-term archiving". Retrieved 2018-07-20.
  7. ^ a b c d "LZMA Specification.7z in LZMA SDK". 7-zip.org.
  8. ^ a b "Lzip Stream Format". Lzip Manual. Retrieved 14 November 2019.
  9. ^ Collin, Lasse; Pavlov, Igor. "lib/xz/xz_dec_lzma2.c". Retrieved 2013-06-16.
  10. ^ "The .xz File Format". 2009-08-27. Retrieved 2013-06-16.
  11. ^ a b c Igor Pavlov (2013). "LZMA SDK (Software Development Kit)". Retrieved 2013-06-16.
  12. ^ "XZ in Java". Archived from the original on 2016-09-21. Retrieved 2013-06-16.
  13. ^ a b Solomon, David (2006-12-19). Data Compression: The Complete Reference (4 ed.). Springer Publishing. p. 245. ISBN 978-1846286025.
  14. ^ Collin, Lasse; Pavlov, Igor. "LZMAEncoderFast.java". Archived from the original on 2012-07-16. Retrieved 2013-06-16.
  15. ^ Collin, Lasse; Pavlov, Igor. "LZMAEncoderNormal.java". Archived from the original on 2012-07-08. Retrieved 2013-06-16.
  16. ^ "Browse /LZMA SDK/4.23". SourceForge. Retrieved 2014-02-12.
  17. ^ "Inno Setup Help". jrsoftware.org. Retrieved 2013-06-16. LZMA2 is a modified version of LZMA that offers a better compression ratio for uncompressible data (random data expands about 0.005%, compared to 1.35% with original LZMA), and optionally can compress multiple parts of large files in parallel, greatly increasing compression speed but with a possible reduction in compression ratio.
  18. ^ "HISTORY of the 7-Zip". 2012-10-26. Retrieved 2013-06-16.
  19. ^ Bauch, Joachim (2010-04-07). "PyLZMA – Platform independent python bindings for the LZMA compression library". Retrieved 2013-06-16.
  20. ^ Birtles, Alan (2006-06-13). "Programming Help: Pascal LZMA SDK". Retrieved 2013-06-16.
  21. ^ Vieru, Andrei (2012-06-28). "compress/lzma package for Go 1". Archived from the original on 2016-09-21. Retrieved 2013-06-16.
  22. ^ "Zip-Ada".
  23. ^ Guillem Jover. "Accepted dpkg 1.17.0 (source amd64 all)". Debian Package QA. Retrieved 2015-10-21.
  24. ^ Diaz, Diaz. "Lzip Benchmarks". LZIP (nongnu).
  25. ^ "What is a Zipx File?". WinZip.com. Retrieved 2016-03-14.
  26. ^ "LZHAM – Lossless Data Compression Codec". Richard Geldreich. LZHAM is a lossless data compression codec written in C/C++ with a compression ratio similar to LZMA but with 1.5–8 times faster decompression speed.

외부 링크