LAPORAN : Resmi
JUDUL : Pengenalan Teknik Kompresi Pada Teks
PERCOBAAN :4
NAMA : Muhammad Dicky Athalla
KELAS : 3D3TA
NRP : 1203191017
DOSEN : Hendy Briantoro S.ST., MT.
TANGGAL : 5 November 2021
TUJUAN
• Mahasiswa mampu memahami teknik-teknik kompresi pada teks
• Mahasiswa mampu menggunakan kompresi teks untuk sistem komunikasi multimedia
DASAR TEORI
Definisi Kompresi Data
Kompresi data adalah sebuah teknik pada ilmu komputer untuk mengecilkan ukuran
data. Banyak orang juga menyebut hal ini dengan memampatkan data. Jadi , data yang ada
dimampatkan menjadi lebih kecil dari ukuran sebenarnya dengan tujuan menghemat ruang
penyimpanan. Apabila kompresi data dilakukan, otomatis Anda hanya membutuhkan
ruang penyimpanan yang lebih kecil. Selain dinilai lebih efisien, kompresi data juga
mempercepat waktu pertukaran data.
Jika Anda masih bingung dengan penjelasan diatas coba simak contoh berikut ini.
Contoh yang paling sering dijumpai adalah menyingkat kata-kata umum yang sering
digunakan seperti “yang” menjadi “yg”. Kompresi data dianggap satu hal yang penting
karena selain mempercepat proses pertukaran data juga mengecilkan kebutuhan
bandwidth. Kompresi data bahkan tidak hanya berlaku untuk teks saja, melainkan gambar
(JPEG, PNG, TIFF), audio (MP3, AAC, RMA, WMA) dan juga video (MPEG, H261,
H263).
Ada beberapa hal yang harus Anda perhatikan agar kompresi data ini dapat berjalan
dengan lancar. Pengiriman data hasil kompresi hanya dapat dilakukan apabila pengirim
dan penerima mempunyai aturan yang sama dalam kompresi data. Selain itu pengirim juga
harus menggunakan algoritma kompresi data yang baku dan pihak penerima pun memakai
teknik dekompresi data yang sama dengan pengirim agar data dapat terbaca.
Algoritma :
- Frekuensi karakter dari string yang akan dikompres dianalisa terlebih dahulu.
Selanjutnya dibuat pohon huffman yang merupakan pohon biner dengan root awal
yang diberi nilai 0 (sebelah kiri) atau 1 (sebelah kanan), sedangkan selanjutnya
untuk dahan kiri selalu diberi nilai 1(kiri) - 0(kanan) dan di dahan kanan diberi nilai
0(kiri) – 1(kanan)
- A bottom-up approach = frekuensi terkecil dikerjakan terlebih dahulu dan
diletakkan ke dalam leaf(daun).
- Kemudian leaf-leaf akan dikombinasikan dan dijumlahkan probabilitasnya
menjadi root di atasnya.
- Misal:
MAMA SAYA
Total = 8 karakter
Jika a belum pernah muncul sebelumnya, sebuah simpul internal dibuat dan kedua
simpul anaknya berisi a dan ART. Kemudian, pohon tersebut diperbaharui untuk
mendapat pohon Huffman dari teks yang sudah dibaca.
Input.
Alphabet A = {a[1], a[2], ..., a[n]}memakai simbol alphabet dengan ukuran n.Set
C = {c[1], c[2], ..., c[n]} dengan konfigurasi nilai simbol, c[i] = nilai (a[i]),
1 <= i <= n.
Output.
Code H(A,C) = {h[1], h[2], ..., h[n]} dengan konfigurasi (biner) codewords,
dimana h[i] adalah codeword dari a[i],
1 <= i <= n.
Goal.
Let S(H) = sum (c[i] * length (h[i])) (1 <= i <= n) akan mengembang dari batas
awal kode H. Harus: S(H) <= S(T) untuk semua kode T(A,C).
Contoh:
Sample-1
Sample-2
Proses Updating
Selama proses encoding dan decoding, pohon sementara harus diperbaharui
untukmendapatkan frekuensi simbol yang benar. Ketika karakter baru diketahui
bobotnya, bobot daun yang berasosiasi dengan karakter tersebut bertambah
satu, dan bobot dari simpul-simpul diatasnya dimodifikasi. Kebenaran pohon
yang terbentuk dilihat dari siblings property pohon tersebut.
Setelah pohon jadi, maka proses selanjutnya adalah sama yaitu encoding dan
decoding.
5) LEMPEL-ZIV-WELCH (LZW)
Algoritma LZW dikembangkan oleh Terry A.Welch dari metode kompresi
sebelumnya yang ditemukan oleh Abraham Lempel dan Jacob Ziv pada tahun 1977.
Algortima ini menggunakan teknik dictionary dalam kompresinya. Dimana string
karakter digantikan oleh kode table yang dibuat setiap ada string yang masuk. Tabel
dibuat untuk referensi masukan string selanjutnya. Ukuran tabel dictionary pada
algoritma LZW asli adalah 4096 sampel atau 12 bit, dimana 256 sampel pertama
digunakan untuk table karakter single (Extended ASCII), dan sisanya digunakan untuk
pasangan karakter atau string dalam data input.
LANGKAH KERJA, HASIL, DAN ANALISA
LANGKAH-LANGKAH
Untuk melalukan percobaan ini diperlukan Python versi 2.7. Langkah-langkah
percobaan dijelaskan seperti berikut ini.
1. Buat aplikasi kompresi dan dekompresi menggunakan metode RLE. Source code
program seperti di bawah ini.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
class RLEPair(object) :
def __init__(self, data=None, length=None):
self.m_data = data
self.m_length = length
class RLE(object) :
def __init__(self):
self.m_RLE = []
self.m_runs=0
self.m_size=0
self.m_RLE.append(RLEPair(p_array[index],chr(1)))
else:
if(ord(self.m_RLE[-1].m_length) ==
255):
self.m_RLE.append(RLEPair(p_array[index],1))
else :
self.m_RLE[-1].m_length =
chr(ord(self.m_RLE[-1].m_length) + 1)
self.m_runs = len(self.m_RLE)
p_array.append(self.m_RLE[currentrun].m_data)
def SaveData(self, p_name):
file = open(p_name, 'wb+')
file.write(struct.pack('i', self.m_size))
file.write(struct.pack('i', self.m_runs))
for i in self.m_RLE : #A la différence de C++
où je pourrais copier un bloc de mémoire dans le
fichier car il est contigüe, je suis obligé d'itérer
sur la liste
file.write(i.m_length)
file.write(i.m_data)
def run_1(filename):
uncompressed=[]
compressed=RLE()
original = open(filename, 'r').read()
compressed.CreateRLE(original)
compressed.SaveData(filename+'.rle')
print 'Original File Size: ' +
str(compressed.m_size)
print 'Compressed File Size: ' +
str(compressed.m_runs*2)
print 'Compression Ratio: ' +
str(float(compressed.m_size)/(compressed.m_runs*2))
compressed.FillArray(uncompressed)
print 'Checking Array Integrity...'
for index in xrange(0, compressed.m_size):
if original[index] != uncompressed[index]:
print 'ERROR, DECOMPRESSION UNSUCCESSFUL!!'
sys.exit(1)
print 'Arrays match!'
def run_2(dataname):
uncompressed=[]
compressed=RLE()
compressed.LoadData(dataname)
compressed.FillArray(uncompressed)
open(dataname[:-4],'w').write("".join(i for i in
uncompressed))
print 'Decompressed to ' + dataname[:-4]
if len(sys.argv) is 1 :
exit('missing source-file name')
if re.match('.+.rle$', sys.argv[1]) :
run_2(sys.argv[1])
else:
run_1(sys.argv[1])
File asli pada percobaan ini berukuran sekitar 11 KB dan hasil kompresi file
menghasilkan file baru dengan ukuran sekitar 1 KB. Di bawah ini merupakan perbandingan
isi dari file asli dengan file hasil kompresi menggunakan metode RLE.
ANALISA
Berdasarkan hasil percobaan terlihat bahwa ukuran file setelah dikompresi akan
menjadi lebih kecil dibandingkan file asli. Namun tidak semua jenis file teks akan
menghasilkan ukuran yang lebih kecil ketika dikompresi menggunakan metode RLE. File yang
akan menghasilkan ukuran lebih kecil adalah file yang memiliki urutan data sama yang saling
berdekatan, sebagai contoh file teks dengan data AAAAAAAAAAAADDDDCCAAAA. Jika
berdasarkan data tersebut maka data yang disimpan setelah dikompresi menggunakan RLE
akan menjadi 12A4D2C4A, yang artinya urutan data karakter A sebanyak 12 dan seterusnya.
Jika file yang dikompresi merupakan file teks dengan data urutan yang berdekatan
banyak yang tidak sama, maka akan menghasilkan ukuran kompresi yang jauh lebih besar jika
dibandingkan dengan file asli.
Saat melakukan dekompresi file menggunakan metode RLE, ukuran file hasil
dekompresi akan sama dengan ukuran file sebelum dilakukan kompresi.
2. STATIC HUFFMAN CODING (SHC)
LANGKAH-LANGKAH
1. Instal terlebih dahulu library yang akan digunakan, pada percobaan ini
menggunakan library bitarray
2. Mengimport modul yang akan digunakan dimana pada percobaan ini
menggunakan modul heapq
3. Memasukkan teks yang akan dikompres
4. Menentukan frekuensi munculnya huruf pada teks yang diinputkan sebelumnya
5. Setelah menentukan frekuensi yang muncul, selanjutnya buat huffman tree pada
program
6. Selanjutnya ke tahap huffman encoding, teks yang dimasukan akan dicetak hasil
kompresinya
7. Terakhir tahap dekompresi atau pada program bernama decoding, file hasil
encoding atau hasil kompresi akan dikembalikan ke ukuran semula
SOURCE CODE
Memasukkan teks yang akan dikompres, teks dalam contoh ini adalah “Urifah
Nur Rohmah” dengan ukuran 17 byte.
Proses kompresi teks. Teks yang semula berukuran 17 byte dikompres sehingga
ukurannya menjadi 5 byte.
Proses dekompresi teks.
ANALISA
3) Inisialisasikan fungsi untuk mencetak kode adaptive huffman coding dari huruf
yang akan digunakan.
4) Inisialisasikan fungsi untuk menghitung frekuensi dari huruf yang akan digunakan.
5) Inisialisasikan fungsi untuk menghasilkan hasil encoding.
7) Masukkan huruf dan banyak frekuensi kedalam pohon biner. Lalu, urutkan semua
node secara ascending berdasarkan banyak frekuensi.
Pada praktikum kali ini dilakukan percobaan kompresi teks menggunakan Algoritma
Adaptive Huffman Coding. Cara kerja pengonversian dengan Adaptive Huffman Coding
ini dengan cara mengkonversikan huruf menjadi biner (encoding) setelah itu hasil
encoding akan kembali dikonversi kedalam huruf (decoding). Selanjutnya kami akan
melakukan 4 percobaan dengan dua kondisi yang berbeda. Dimana kondisi yang pertama
adalah ukuran file asli pada percobaan pertama dan kedua berbeda, kemudian kondisi yang
kedua adalah ukuran file asli percobaan ketiga dan keempat sama.
Kondisi Pertama
Percobaan pertama didapatkan ukuran file Sebelum Dikompresi sebesar 112 bit dan
Setelah Dikompresi sebesar 48 bit, sehingga didapatkan presentase konversi sebesar
42,8%
Percobaan kedua didapatkan ukuran file sebelum dikompresi sebesar 152 bit dan
setelah dikompresi sebesar 69 bit, sehingga didapatkan presentase konversi sebesar 45,4%
Dari percobaan pertama dan kedua didapatkan bahwa presentase hasil konversi
berbeda. Dimana pada percobaan kedua hasilnya lebih besar dari percobaan pertama. Hal
ini terjadi karena besar file dan banyak karakter mempengaruhi besar file dan presentase
hasil konversi.
Kondisi Kedua
Percobaan ketiga didapatkan ukuran file sebelum dikompresi sebesar 80 bit dan setelah
dikompresi sebesar 10 bit, sehingga didapatkan presentase konversi sebesar 12,5%
Percobaan keempat didapatkan ukuran file sebelum dikompresi sebesar 80 bit dan
setelah dikompresi sebesar 15 bit, sehingga didapatkan presentase konversi sebesar
18,75%
Dari percobaan ketiga dan keempat didapatkan bahwa hasil ukuran dan presentase hasil
konversi berbeda, walaupun ukuran file asli sama. Hal ini terjadi karena ragam karakter
percobaan ketiga dan keempat berbeda. Dimana semakin banyak ragam karakter, maka
ukuran file dan presentase hasil konversi semakin besar. Sebaliknya makin sedikit ragam
karakter, maka ukuran file dan presentase hasil konversi semakin kecil. Hal ini
dikarenakan pada Adaptive Huffman Coding memiliki cara kerja bahwa karakter yang
sama akan ditambahkan dalam frekuensi karakter tersebut dan hanya akan dikonversi satu
kali.
4. SHANON FANO (SFA)
LANGKAH-LANGKAH
• Buka IDE Python menggunakan Visual Studio Code.
def decrypt_data(path):
file = open(path, 'rb+')
char_counter = os.path.getsize(path)
if char_counter == 0:
print('ERROR: SOURCE FILE IS EMPTY')
return
json_bytes = b''
is_loading_json_dic = True
while is_loading_json_dic:
char = file.read(1)
#print(char)
json_bytes += char
char_counter -= 1
if char == b'}':
is_loading_json_dic = False
if char_counter < 0:
print('ERROR: INVALID SOURCE FILE')
return
codes_dict = json.loads(json_bytes.decode("utf-8"))
print(codes_dict)
get_decoded_string(codes_dict, bitstring)
def get_decoded_string(codes_dict, bitstring):
# odwrócenie słownika
new_json = {}
for k, v in codes_dict.items():
new_json[v] = k
decoded_string = ""
substring = ""
for bit in bitstring:
substring += bit
if is_json_key_present(new_json, substring):
if new_json[substring] == "_EOT":
break
elif new_json[substring] == "_NewLine":
decoded_string += "\n"
elif new_json[substring] == "_Space":
decoded_string += " "
elif new_json[substring] == "_CurlyCloseB":
decoded_string += "}"
else:
decoded_string += new_json[substring]
substring = ""
return True
char_probability = OrderedDict(sorted(char_probability.items()))
# zapis słownika znaków i ich kodów binarnych do pliku oraz samych danych binarnych
with open(encoded_filename, 'bw') as f:
f.write(bytes(json.dumps(codes_dict, ensure_ascii=False).encode('utf8')))
bitstring.BitArray(bin=bitstr).tofile(f)
end = time.time()
print("Encoding finished in " + str(end - start) + " seconds.")
if len(sorted_probability_dict) == 1:
return
if len(sorted_probability_dict) == 2:
dict_keys = list(sorted_probability_dict.keys())
code_tree.add_to_tree(path + [0], dict_keys[0])
code_tree.add_to_tree(path + [1], dict_keys[1])
return
if __name__ == '__main__':
while True:
print("\nShannon-Fano encryption and decryption utility.")
inp1 = input("Do you want to encrypt or decrypt file? (e/d): ")
if inp1 == 'e':
inp_e1 = input("Relative path to file: ")
if not os.path.isfile(inp_e1):
print('ERROR: FILE NOT FOUND\n')
continue
inp_e2 = input("Encoded file name: ")
encrypt_data(inp_e1, inp_e2 + ".pack")
elif inp1 == 'd':
inp = input("Relative path to file: ")
if not os.path.isfile(inp):
print('ERROR: FILE NOT FOUND\n')
continue
decrypt_data(inp)
else:
print('ERROR: WRONG COMMAND\n')
continue
inp2 = input("\nDo you want to continue with another file? (y/n): ")
if inp2 == 'n':
break
Langkah Kerja :
1. Buka IDE python seperti misalnya Visual studio code
Shannon-Fano code :
{'_Space': '000', 'e': '001', 't': '0100', 'a': '0101', 'i': '0110', 's': '0111', 'o': '1000', 'n':
'1001', 'r': '10100', 'l': '10101', 'h': '10110', 'd': '10111', 'u': '11000', 'p': '110010', 'm':
'110011', 'c': '11010', 'g': '110110', 'w': '110111', 'y': '111000', 'f': '111001', 'b':
'111010', 'v': '1110110', ',': '1110111', '.': '1111000', '_NewLine': '1111001', 'k':
'11110100', 'T': '11110101', '-': '11110110', '0': '111101110', 'I': '111101111', 'S':
'11111000', 'A': '111110010', '’': '111110011', 'C': '111110100', 'L': '111110101',
'E': '111110110', '5': '1111101110', 'G': '1111101111', 'x': '1111110000', '7':
'1111110001', 'D': '1111110010', 'O': '1111110011', 'W': '1111110100', '2':
'1111110101', 'F': '11111101100', 'H': '11111101101', 'z': '1111110111', '/':
'11111110000', '1': '11111110001', '8': '1111111001', 'M': '11111110100', 'R':
'11111110101', 'B': '11111110110', 'P': '11111110111', 'V': '11111111000', 'q':
'11111111001', '%': '111111110100', '3': '111111110101', ':': '111111110110', '?':
'111111110111', 'N': '11111111100', 'j': '111111111010', '4': '1111111110110', '6':
'1111111110111', '9': '1111111111000', 'U': '1111111111001', 'Y':
'111111111101', '_EOT': '1111111111100', '~': '1111111111101', '“':
'1111111111110', '”': '1111111111111'}
Tidak adanya perbedaan antara file asli dan file hasil dekompresi ini sesuai dengan sifat
shannon fano algorithm yakni Lossless Compresion.
Dilihat dari shannon-code yang dihasilkan, sesuai dengan algoritmanya, karakter
dengan frekuensi kemunculan tertinggi akan memiliki bit yang paling kecil. Dalam kasus ini
karakter '_Space' lah yang memiliki frekuensi tertinggi dengan bit '000'. Sebaliknya, karakter
'”' memiliki frekuensi kemunculan terkecil akan memiliki bit terbesar yakni '1111111111111'
5. LEMPEL-ZIV-WELCH (LZW)
LANGKAH-LANGKAH
Untuk melakukan praktikum ini dapat mengikuti Langkah-langkah berikut
1. Buat program encoder dan decoder file string menggunakan algoritma Lempel-Ziv-
Welch (LZW) dalam Bahasa python.
2. Membuat file yang akan dilakukan kompresi dalam format file .txt
3. Jalankan script encoder.py menggunakan CMD atau terminal untuk melakukan
kompresi. Command yang dijalankan adalah python encoder.py <filename.txt>
<number of bits>
4. Hasil encoder memiliki format .lzw dan disimpan pada folder yang sama.
5. Untuk melakukan decompress menjalankan script decoder.py. Command yang
dijalankan adalah python decoder.py <filename.lzw> <number of bits>
HASIL PERCOBAAN
Berikut merupakan hasil percobaan dari kompresi dan dekompresi file string dalam
format .txt
File asli memiliki ukuran 104 bytes. Ketika dilakukan kompresi menghasilkan ukuran 174
bytes. Kompresi menghasilkan file baru dengan format .lzw.
File hasil kompresi tersebut didekompresi kembali, menghasilkan ukuran file sama
dengan file asli. Kemudian melakukan percobaan kedua dengan ukuran file asli sebesar
3576 bytes. Ketika dilakukan kompresi menghasilkan ukuran 2880 bytes.
Dari file lzw didekompresi menghasilkan ukuran file yang sama dengan file asli, yaitu
sebesar 3576 bytes.
ANALISA
Dalam kompresi LZW digunakan tabel kode, dengan 4096 sebagai jumlah entri tabel.
Setiap karakter didalam Kode ASCII disimpan dengan ukuran 8 bit biner, yang mana
ukurannya bisa mencapai 256. Algoritma ini mencoba untuk memperluas library menjadi
9 sampai 12 bit per karakter. Kode 0-255 dalam tabel kode ditugaskan untuk mewakili byte
tunggal dari file input. Ketika encoding dimulai, tabel kode hanya berisi 256 entri pertama,
dengan sisa tabel kosong. Kompresi dicapai dengan menggunakan kode 256 hingga 4095
untuk mewakili urutan byte. Ketika Encoding berlanjut, LZW mengidentifikasi urutan
berulang dalam data, dan menambahkannya ke tabel kode. Kompresi pada algoritma ini
tidak selalu berjalan dengan baik, terutama dengan string pendek dan beragam. Tetapi
bagus untuk mengompresi data yang berlebihan, dan tidak harus menyimpan kamus baru
dengan data.
Kemudian pada proses decoding dicapai dengan mengambil setiap kode dari file
terkompresi dan menerjemahkannya melalui tabel kode untuk menemukan karakter atau
karakter yang diwakilinya. Pada hasil dekompresi isi file tetap sama dengan isi file asli.
Karena LZW ini menggunakan metode lossless compression.
TABEL HASIL KOMPRESI
DENGAN 5 METODE BERBEDA
RLE 11 1 11
2. SHC
• Semakin sering karakter pada teks itu muncul, maka semakin pendek representasi
bitnya. Sebaliknya, semakin jarang karakter pada teks itu muncul, maka semakin
panjang representasi bit untuk karakter tersebut.
4. SHANON FANO
• Tidak adanya perbedaan antara file asli dan file hasil dekompresi ini sesuai dengan
sifat shannon fano algorithm yakni Lossless Compresion.
• Dilihat dari shannon-code yang dihasilkan, sesuai dengan algoritmanya, karakter
dengan frekuensi kemunculan tertinggi akan memiliki bit yang paling kecil. Dalam
kasus ini karakter '_Space' lah yang memiliki frekuensi tertinggi dengan bit '000'.
Sebaliknya, karakter '”' memiliki frekuensi kemunculan terkecil akan memiliki bit
terbesar yakni '1111111111111'
5. LEMPEL-ZIV-WELCH
• Kompresi LZW termasuk algoritma dengan metode lossless compression, karena
tidak ada informasi yang hilang tetapi hanya mengurangi bit dengan
mengidentifikasi dan menghilangkan redundansi statistik.
• Kompresi dengan Lempel-Ziv-Welch tidak selalu berjalan dengan baik, terutama
dengan string pendek dan beragam. Tetapi bagus untuk mengompresi data yang
berlebihan, dan tidak harus menyimpan kamus baru dengan data.