Konversi Sistem Bilangan: Message Length di Network Protocol
Melanjutkan materi sebelumnya tentang PIN Block, kali ini kita akan membahas aplikasi konversi sistem bilangan dalam konteks network transmission. Khususnya, bagaimana cara mengirim informasi panjang message dalam protokol komunikasi seperti ISO8583.
Permasalahan: Memisahkan Antar Message
Dalam komunikasi socket antara dua aplikasi (misalnya terminal ATM dengan server bank), data dikirim sebagai stream of bytes yang kontinyu. Bagaimana cara receiver tahu di mana satu message berakhir dan message berikutnya dimulai?
Ada dua pendekatan umum:
1. Prefix Message Length (Depan)
Kirim panjang message sebelum message itu sendiri:
[Length: 325][Message data 325 byte]
Receiver membaca length dulu, baru kemudian membaca sejumlah byte sesuai length tersebut.
2. Trailer Byte (Belakang)
Tambahkan karakter khusus di akhir message sebagai delimiter:
[Message data][ETX]
Receiver terus membaca sampai menemukan karakter ETX (End of Text).
Pada artikel ini kita fokus pada prefix message length yang lebih umum digunakan, terutama di protokol perbankan.
Dua Cara Mengirim Length
Ada dua cara mengirim informasi length: ASCII dan Binary.
1. Paling Mudah: ASCII Channel (4 byte)
Cara paling mudah adalah mengirim length dalam bentuk ASCII 4 byte. Misalnya jika message panjangnya 325 byte, kita kirim string "0325".
Keuntungan:
- Human readable: bisa langsung dibaca manusia
- Mudah di-debug: tinggal lihat hex dump
- Implementasi sederhana
Keterbatasan:
- Maksimal length: 9999 byte (4 digit)
- Boros: butuh 4 byte untuk setiap message
Contoh:
Message length 325 byte dikirim sebagai ASCII "0325":
Dalam memori/network:
30 33 32 35 (hex)
0 3 2 5 (ASCII)
Setiap digit desimal dikonversi ke ASCII character:
0→ ASCII 0x303→ ASCII 0x332→ ASCII 0x325→ ASCII 0x35
2. Paling Hemat: Port Channel (2 byte Binary)
Cara yang lebih efisien adalah mengirim length dalam bentuk binary 2 byte dengan format MSB/LSB (Most Significant Byte / Least Significant Byte), juga dikenal sebagai network byte order atau big-endian.
Keuntungan:
- Hemat: hanya 2 byte
- Kapasitas: maksimal 65535 byte (2¹⁶ - 1)
Keterbatasan:
- Tidak human readable
- Perlu konversi MSB/LSB
- Lebih susah debugging tanpa tools
Konversi Decimal ke Hexadecimal MSB/LSB
Sekarang kita masuk ke perhitungan yang menjadi inti dari pembelajaran sistem bilangan. Bagaimana cara mengkonversi length dalam desimal menjadi 2 byte hexadecimal dengan format MSB/LSB?
Contoh: Length 325 byte
Langkah 1: Konversi Decimal ke Binary
325 (decimal) = ? (binary)
325 ÷ 2 = 162 sisa 1
162 ÷ 2 = 81 sisa 0
81 ÷ 2 = 40 sisa 1
40 ÷ 2 = 20 sisa 0
20 ÷ 2 = 10 sisa 0
10 ÷ 2 = 5 sisa 0
5 ÷ 2 = 2 sisa 1
2 ÷ 2 = 1 sisa 0
1 ÷ 2 = 0 sisa 1
Baca dari bawah ke atas:
325 (decimal) = 1 0100 0101 (binary)
Langkah 2: Pisahkan Menjadi MSB dan LSB
Lengkapi dengan leading zeros menjadi 16 bit:
0000 0001 0100 0101
|_______| |_______|
MSB LSB
MSB = 0000 0001 = 1
LSB = 0100 0101 = 69
Langkah 3: Konversi ke Hexadecimal
Binary ke Hex conversion table:
0000 = 0 0100 = 4 1000 = 8 1100 = C
0001 = 1 0101 = 5 1001 = 9 1101 = D
0010 = 2 0110 = 6 1010 = A 1110 = E
0011 = 3 0111 = 7 1011 = B 1111 = F
Konversi MSB:
MSB: 0000 0001
0 1 = 0x01
Konversi LSB:
LSB: 0100 0101
4 5 = 0x45
Hasil: 01 45
Jadi message length 325 byte direpresentasikan sebagai 2 byte hexadecimal: 01 45
Mengapa MSB/LSB Penting?
Format MSB/LSB atau big-endian adalah standar untuk network transmission (RFC 1700). Byte yang paling signifikan (MSB) dikirim duluan.
Ada juga format kebalikannya: LSB/MSB atau little-endian yang digunakan di arsitektur processor Intel x86. Jadi untuk nilai 325:
- Big-endian (network):
01 45 - Little-endian (Intel):
45 01
Dalam network programming, kita harus menggunakan network byte order (big-endian/MSB first).
Konversi Hexadecimal MSB/LSB ke Decimal
Sekarang kebalikannya: receiver menerima 2 byte hex, bagaimana cara mengkonversinya kembali ke decimal?
Contoh: Menerima Header 01 45
Langkah 1: Identifikasi MSB dan LSB
Byte 1: 0x01 → MSB (Most Significant Byte)
Byte 2: 0x45 → LSB (Least Significant Byte)
Langkah 2: Konversi Hex ke Binary untuk Setiap Byte
MSB: 0x01 = 0000 0001 (binary)
LSB: 0x45 = 0100 0101 (binary)
Langkah 3: Gabungkan Menjadi 16 Bit
MSB adalah byte pertama (8 bit tinggi), LSB adalah byte kedua (8 bit rendah):
01 45 (hex) = 0000 0001 0100 0101 (binary 16 bit)
|_______| |_______|
MSB LSB
(bit 8-15) (bit 0-7)
Langkah 4: Konversi 16 Bit ke Decimal
Setiap posisi bit dalam binary memiliki nilai berdasarkan pangkat 2:
Posisi bit: 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Nilai posisi: 2¹⁵ 2¹⁴ 2¹³ 2¹² 2¹¹ 2¹⁰ 2⁹ 2⁸ 2⁷ 2⁶ 2⁵ 2⁴ 2³ 2² 2¹ 2⁰
Bit value: 0 0 0 0 0 0 0 1 0 1 0 0 0 1 0 1
Hitung nilai decimal dengan menjumlahkan posisi bit yang bernilai 1:
0000 0001 0100 0101 (binary)
= 1×2⁸ + 1×2⁶ + 1×2² + 1×2⁰
= 1×256 + 1×64 + 1×4 + 1×1
= 256 + 64 + 4 + 1
= 325 (decimal)
Jadi header 01 45 berarti message length adalah 325 byte.
Studi Kasus: Implementasi di jPOS
Setelah memahami perhitungan manual, mari kita lihat bagaimana implementasi nyata di dunia production.
Tentang jPOS
jPOS bukan library sembarangan. Ini adalah framework production-grade yang digunakan oleh ratusan bank dan payment processor di seluruh dunia untuk menangani transaksi bernilai triliunan rupiah setiap harinya.
Fakta tentang jPOS:
- Usia: Dikembangkan sejak tahun 1998, sudah lebih dari 25 tahun di production
- Pengguna: Bank-bank besar, ATM switcher, payment gateway, dan fintech di 90+ negara
- Skala: Menangani miliaran transaksi per tahun dengan nilai total triliunan dollar
- Reliabilitas: Uptime 99.99%, dirancang untuk mission-critical financial systems
- Open Source: Kode sumber terbuka (AGPL), bisa di-audit oleh siapa saja
- Sertifikasi: Sudah digunakan untuk sistem yang comply dengan PCI-DSS, ISO 8583, EMV
Ketika ATM mengeluarkan uang, ketika kartu debit digesek di merchant, ketika transfer antar bank terjadi - ada kemungkinan besar transaksi itu melewati sistem yang dibangun dengan jPOS.
Ini bukan kode prakarya atau project kuliah. Ini adalah kode yang:
- Harus bekerja 24/7/365 tanpa boleh down
- Menangani uang sungguhan milik orang sungguhan
- Jika bug, bisa menyebabkan kerugian miliaran rupiah
- Harus aman dari hacker yang mencoba mencuri uang
- Harus cepat (response time < 1 detik) meskipun ribuan transaksi concurrent
Jadi ketika kalian belajar konversi sistem bilangan ini, kalian sedang belajar hal yang sama dengan yang digunakan oleh programmer senior yang membangun infrastruktur perbankan dunia.
Kode Production dari jPOS
Sekarang mari kita lihat source code asli dari PostChannel.java, yang mengimplementasikan pengiriman message length dalam format 2 byte binary MSB/LSB:
Method sendMessageLength
protected void sendMessageLength(int len) throws IOException {
serverOut.write (len >> 8);
serverOut.write (len);
}
Method getMessageLength
protected int getMessageLength() throws IOException, ISOException {
byte[] b = new byte[2];
serverIn.readFully(b,0,2);
return ((int)b[0] & 0xFF) << 8 |
(int)b[1] & 0xFF;
}
Kode yang sangat singkat, bukan? Hanya 2 baris untuk mengirim, dan 3 baris untuk membaca. Tapi di balik kode singkat ini, ada perhitungan yang sama persis dengan yang kita pelajari di atas. Bedanya, programmer menggunakan bitshift operator untuk membuatnya lebih ringkas.
Cara Kerja Bitshift Operator
Ada empat operator bitwise yang digunakan:
- Right Shift (
>>): Menggeser bit ke kanan - Left Shift (
<<): Menggeser bit ke kiri - AND (
&): Masking bit dengan operasi AND bitwise - OR (
|): Menggabungkan dua nilai dengan operasi OR bitwise
Contoh 1: Right Shift untuk Mendapatkan MSB
Kita punya len = 325:
325 (decimal) = 0000 0001 0100 0101 (binary 16 bit)
Operasi len >> 8 berarti: geser ke kanan 8 bit
0000 0001 0100 0101 (325 dalam 16 bit)
>> 8
─────────────────────
0000 0000 0000 0001 (1 dalam 16 bit)
8 bit yang di sebelah kanan “jatuh” dan hilang, 8 bit yang di sebelah kiri bergeser ke kanan. Hasilnya adalah MSB = 1.
Verifikasi perhitungan:
325 >> 8 = 325 ÷ 2⁸ = 325 ÷ 256 = 1 (hasil bagi bulat)
Contoh 2: Ambil LSB Langsung
Untuk mendapatkan LSB, kita tinggal kirim len langsung. Kenapa?
Karena method write() hanya mengambil 8 bit terendah dari parameter yang dikirim. Jadi meskipun kita kirim integer 16 bit (atau bahkan 32 bit), yang dikirim ke network hanya 8 bit terakhir (LSB).
325 (decimal) = 0000 0001 0100 0101 (binary 16 bit)
|_______|
↓
hanya ini yang dikirim
0100 0101 = 69
Ini adalah jawaban untuk bonus point: Mengapa di baris serverOut.write(len) kita mengirim seluruh len, bukan cuma LSB?
Jawabannya: method write() secara otomatis hanya mengambil 8 bit terendah (LSB). Kita tidak perlu melakukan operasi khusus untuk mengekstrak LSB. Method tersebut sudah menanganinya untuk kita.
Ini bukan asumsi atau tebakan, tapi dokumentasi resmi dari Java. Menurut Javadoc OutputStream.write(int):
write(int b)
Writes the specified byte to this output stream. The general contract for write is that one byte is written to the output stream. The byte to be written is the eight low-order bits of the argument b. The 24 high-order bits of b are ignored.
Jadi meskipun parameter bertipe int (32 bit), yang ditulis ke stream hanya 8 bit terendah. Inilah mengapa serverOut.write(len) otomatis mengambil LSB tanpa perlu operasi bitwise tambahan.
Contoh 3: Operator OR untuk Menggabungkan Bit
Sebelum kita bahas cara membaca message length, kita perlu paham dulu operator OR (|).
Operator OR bitwise bekerja per bit dengan aturan:
0 | 0 = 0
0 | 1 = 1
1 | 0 = 1
1 | 1 = 1
Intinya: hasilnya 1 jika salah satu atau kedua bit bernilai 1.
Contoh sederhana:
5 | 2
5 = 0101 (binary)
2 = 0010 (binary)
---- OR
0111 = 7 (decimal)
Penjelasan per bit:
- Bit 0: 1 | 0 = 1
- Bit 1: 0 | 1 = 1
- Bit 2: 1 | 0 = 1
- Bit 3: 0 | 0 = 0
Kasus khusus yang penting: Jika dua bilangan tidak ada bit yang “bentrok” (tidak ada posisi bit yang sama-sama 1), maka OR sama dengan penjumlahan:
256 | 69
256 = 0000 0001 0000 0000 (binary)
69 = 0000 0000 0100 0101 (binary)
--------------------- OR
0000 0001 0100 0101 = 325 (decimal)
Perhatikan bahwa tidak ada posisi bit yang sama-sama bernilai 1, sehingga:
256 | 69 = 256 + 69 = 325
Untuk perhitungan MSB dan LSB, tidak akan terjadi bentrok, karena MSB mengisi 2 blok di sebelah kiri, dan LSB mengisi 2 blok di kanan. Sehingga operator | ini bisa digunakan untuk menjumlahkan MSB dan LSB.
Contoh 4: Operator AND untuk Masking Bit
Operator AND bitwise (&) bekerja per bit dengan aturan:
0 & 0 = 0
0 & 1 = 0
1 & 0 = 0
1 & 1 = 1
Intinya: hasilnya 1 hanya jika kedua bit bernilai 1.
Operator AND sering digunakan untuk masking, yaitu mengambil bit-bit tertentu saja dan membuang bit lainnya.
Contoh dengan 0xFF (masking 8 bit terendah):
0xFF = 1111 1111 (8 bit)
= 0000 0000 1111 1111 (16 bit)
Misalnya kita punya bilangan 325 dalam byte yang di-cast ke int:
(int)325 & 0xFF
325 (int 32 bit) = 0000 0000 0000 0000 0000 0001 0100 0101
0xFF (int 32 bit) = 0000 0000 0000 0000 0000 0000 1111 1111
─────────────────────────────────────── AND
0000 0000 0000 0000 0000 0000 0100 0101 = 69
Perhatikan bahwa:
- Bit yang di-AND dengan 1 akan tetap (keep original value)
- Bit yang di-AND dengan 0 akan jadi 0 (mask out)
Jadi & 0xFF artinya: ambil 8 bit terendah saja, buang 24 bit sisanya.
Mengapa perlu masking dengan 0xFF?
Dalam Java, tipe byte adalah signed (-128 sampai 127). Ketika byte negatif di-cast ke int, terjadi sign extension di mana bit-bit tinggi diisi dengan 1.
Contoh:
byte b = (byte)0xFF; // -1 dalam signed byte
(int)b = 1111 1111 1111 1111 1111 1111 1111 1111 // sign extension!
= -1 (int)
(int)b & 0xFF = 0000 0000 0000 0000 0000 0000 1111 1111
= 255 (int) // yang kita inginkan!
Dengan masking & 0xFF, kita memastikan hasilnya selalu unsigned (0-255).
Contoh 5: Gabungan Semua Operator untuk Membaca MSB/LSB
Sekarang kebalikannya, ketika membaca 2 byte dari network:
byte[] b = new byte[2]; // b[0] = 0x01, b[1] = 0x45
return ((int)b[0] & 0xFF) << 8 | (int)b[1] & 0xFF;
Mari kita uraikan step by step:
Langkah 1: Baca MSB dan konversi ke int
b[0] = 0x01 = 0000 0001 (byte 8 bit)
(int)b[0] = 0000 0000 0000 0000 0000 0000 0000 0001 (int 32 bit)
Langkah 2: Masking dengan 0xFF
Operasi & 0xFF memastikan hanya 8 bit terendah yang diambil (seperti yang sudah kita pelajari di Contoh 4, untuk menghilangkan sign extension):
(int)b[0] & 0xFF = 0000 0000 0000 0000 0000 0000 0000 0001 = 1
Langkah 3: Left Shift 8 bit
((int)b[0] & 0xFF) << 8
= 1 << 8
= 0000 0001 → geser kiri 8 bit → 0000 0001 0000 0000
= 256 (decimal)
Langkah 4: Proses LSB
b[1] = 0x45 = 0100 0101
(int)b[1] & 0xFF = 0000 0000 0000 0000 0000 0000 0100 0101 = 69
Langkah 5: OR keduanya
Operator | (OR) menggabungkan kedua nilai (seperti yang sudah kita pelajari di Contoh 3):
0000 0001 0000 0000 (MSB yang sudah di-shift = 256)
| 0000 0000 0100 0101 (LSB = 69)
─────────────────────
0000 0001 0100 0101 = 325
Verifikasi perhitungan:
256 | 69 = 256 + 69 = 325 ✓
Visualisasi Lengkap
Mari kita gabungkan semua operasi untuk len = 325:
Pengiriman (sendMessageLength):
len = 325 = 0000 0001 0100 0101
Kirim MSB:
len >> 8 = 0000 0000 0000 0001 = 1 → kirim byte 0x01
Kirim LSB:
len (ambil 8 bit terendah) = 0100 0101 = 69 → kirim byte 0x45
Terkirim ke network: 01 45
Penerimaan (getMessageLength):
Terima dari network: 01 45
Baca byte[0] = 0x01:
(int)b[0] & 0xFF = 1
1 << 8 = 256
Baca byte[1] = 0x45:
(int)b[1] & 0xFF = 69
Gabungkan:
256 | 69 = 325
Mengapa Menggunakan Bitshift?
- Efisien: Operasi bitshift adalah operasi CPU paling cepat
- Ringkas: Tidak perlu loop atau perhitungan kompleks
- Standard: Ini adalah cara standard dalam network programming
- Readable: Programmer yang paham binary akan langsung mengerti
Sekarang kalian sudah paham bahwa rumus yang terlihat “magic” seperti len >> 8 sebenarnya adalah cara ringkas untuk melakukan perhitungan yang sama dengan yang kita pelajari secara manual. Tidak ada yang magic, semuanya bisa dijelaskan dengan konversi sistem bilangan yang sudah kita pelajari!
Latihan Soal
Untuk mengasah pemahaman, coba kerjakan soal-soal berikut:
Soal 1: Decimal ke Hex MSB/LSB
Konversi length berikut ke format 2 byte hexadecimal MSB/LSB:
a) 200 byte b) 512 byte c) 1024 byte d) 4096 byte
a) 200 decimal = 0x00C8
- Binary: 0000 0000 1100 1000
- MSB: 0000 0000 = 0x00
- LSB: 1100 1000 = 0xC8
b) 512 decimal = 0x0200
- Binary: 0000 0010 0000 0000
- MSB: 0000 0010 = 0x02
- LSB: 0000 0000 = 0x00
c) 1024 decimal = 0x0400
- Binary: 0000 0100 0000 0000
- MSB: 0000 0100 = 0x04
- LSB: 0000 0000 = 0x00
d) 4096 decimal = 0x1000
- Binary: 0001 0000 0000 0000
- MSB: 0001 0000 = 0x10
- LSB: 0000 0000 = 0x00
Soal 2: Hex MSB/LSB ke Decimal
Konversi header hexadecimal berikut ke decimal:
a) 00 64 b) 02 00 c) 03 E8 d) 10 00
a) 00 64
- MSB: 0x00 = 0000 0000 = 0
- LSB: 0x64 = 0110 0100 = 64 + 32 = 100
- Total: 100 decimal
b) 02 00
- MSB: 0x02 = 0000 0010 = 2
- LSB: 0x00 = 0000 0000 = 0
- Total: (2 × 256) + 0 = 512 decimal
c) 03 E8
- MSB: 0x03 = 0000 0011 = 2 + 1 = 3
- LSB: 0xE8 = 1110 1000 = 128 + 64 + 32 + 8 = 232
- Total: (3 × 256) + 232 = 1000 decimal
d) 10 00
- MSB: 0x10 = 0001 0000 = 16
- LSB: 0x00 = 0000 0000 = 0
- Total: (16 × 256) + 0 = 4096 decimal
Soal 3: ASCII vs Binary
Message dengan length 999 byte akan dikirim melalui network. Berapa byte overhead untuk header jika menggunakan:
a) ASCII channel (4 byte) b) Binary channel (2 byte)
Jika dalam satu hari dikirim 1 juta message, berapa total bandwidth yang bisa dihemat dengan menggunakan binary channel?
a) ASCII: 4 byte overhead per message b) Binary: 2 byte overhead per message
Penghematan per message: 4 - 2 = 2 byte
Total penghematan untuk 1 juta message: 2 byte × 1,000,000 = 2,000,000 byte = 2 MB
Ini belum termasuk penghematan di bandwidth reply message. Jika setiap request ada reply, penghematan bisa 2× lipat = 4 MB per hari.
Kapan Menggunakan ASCII vs Binary?
ASCII Channel cocok untuk:
- Development dan testing (mudah debugging)
- Message size selalu < 10000 byte
- Legacy system yang sudah pakai ASCII
- Tim yang belum familiar dengan binary protocol
Binary Channel cocok untuk:
- Production dengan volume tinggi
- Message size bisa > 9999 byte
- Optimasi bandwidth penting
- Modern system dengan tools debugging yang baik
Ringkasan Rumus
Untuk referensi cepat:
Decimal → Hex MSB/LSB
MSB = Length ÷ 256
LSB = Length mod 256
Hex MSB/LSB → Decimal
Length = (MSB × 256) + LSB
Kapasitas Maximum
2 byte = 16 bit = 2¹⁶ = 65536 nilai (0 s/d 65535)
4 byte ASCII = 4 digit = 10⁴ = 10000 nilai (0000 s/d 9999)
Penutup
Konversi sistem bilangan dalam konteks message length ini adalah aplikasi nyata dari materi kuliah sistem bilangan. Sama seperti materi PIN Block sebelumnya, pemahaman tentang konversi decimal-binary-hexadecimal sangat penting dalam:
- Network Programming: Implementasi protokol komunikasi
- System Integration: Integrasi antar sistem yang berbeda
- Performance Optimization: Memilih format yang tepat untuk efisiensi
- Debugging: Troubleshooting masalah di level network packet
Tanpa pemahaman ini, kita hanya bisa copy-paste code tanpa mengerti apa yang sebenarnya terjadi. Dan ketika ada masalah (pasti akan ada), kita tidak akan bisa troubleshoot dengan efektif.
Ini adalah skill fundamental yang akan terus berguna sepanjang karir di bidang teknologi informasi, khususnya untuk yang bekerja di:
- Payment system
- Banking infrastructure
- Network protocol implementation
- Embedded systems
- IoT devices
Selamat berlatih!



