Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions i18n/id-ID.ziggy
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"site_title": "Zig Cookbook",
"introduction": "Pengenalan",
"contributing": "Kontribusi",
"license": "Lisensi",
"toggle_toc": "Alih daftar isi",
"prev": "Sebelumnya: ",
"next": "Selanjutnya: ",
"languages_menu": "Halaman ini tersedia dalam bahasa-bahasa berikut",
"footer_copyright": "Lisensi: text: CC BY-SA 4.0; code: MIT",
Comment thread
jiacai2050 marked this conversation as resolved.
}
2 changes: 1 addition & 1 deletion layouts/section.shtml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
</div>
</ctx>
<div id="footer">
<div>&copy; 2023 - 2025
<div>&copy; 2023 - 2026
| <a href="https://github.com/zigcc/zig-cookbook">GitHub</a>
| <a href="http://ziglang.cc">Zig 中文社区</a>
| <a href="http://course.ziglang.cc">Zig 圣经</a>
Expand Down
10 changes: 10 additions & 0 deletions src/id-ID/01-01-read-file-line-by-line.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
.title = "Pembacaan file baris per baris",
.date = "2026-04-29 10:58",
.author = "ZigCC",
.layout = "section.shtml",
---

Terdapat tipe `Reader` di Zig, yang mana menyediakan berbagai metode untuk membaca file, seperti `readAll`, `readInt`. Di sini kita akan menggunakan `takeDelimiter` untuk pemisahan baris.

[]($code.siteAsset('src/01-01.zig').language('zig'))
10 changes: 10 additions & 0 deletions src/id-ID/01-02-mmap-file.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
.title = "file Mmap",
.date = "2026-04-29 10:59",
.author = "ZigCC",
.layout = "section.shtml",
---

Pembuatan memory map dari sebuah file dapat menggunakan [mmap](https://man7.org/linux/man-pages/man2/mmap.2.html) dan mensimulasikan beberapa pembacaan non-sekuensial dari file tersebut. Menggunakan memory map berarti kamu hanya perlu mengindeks ke dalam sebuah slice daripada harus berurusan dengan seek dalam menavigasi file.

[]($code.siteAsset('src/01-02.zig').language('zig'))
12 changes: 12 additions & 0 deletions src/id-ID/01-03-file-modified-24h-ago.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
.title = "Pencarian file-file yang telah diubah dalam 24 jam terakhir",
.date = "2026-04-29 11:06",
.author = "ZigCC",
.layout = "section.shtml",
---

Dapatkan direktori kerja saat ini dengan memanggil `Io.Dir.cwd()`, kemudian lakukan iterasi file menggunakan `walk()`, yang akan secara rekursif mengulangi entri dalam direktori.

Untuk setiap entri, kita periksa apakah itu file, dan menggunakan `statFile()` untuk mengambil metadata file.

[]($code.siteAsset('src/01-03.zig').language('zig'))
15 changes: 15 additions & 0 deletions src/id-ID/01-04-file-exists.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
.title = "Cek keberadaan file",
.date = "2026-04-29 11:13",
.author = "ZigCC",
.layout = "section.shtml",
---

Contoh ini menggunakan, `access` dalam memverifikasi keberadaan file; namun, agar dapat berfungsi dengan benar, seseorang harus secara khusus melakukan pemeriksaan tipe error `FileNotFound`.

[]($code.siteAsset('src/01-04.zig').language('zig'))

Namun, ada jebakan yang dijelaskan dalam [dokumentasinya](https://github.com/ziglang/zig/blob/0.13.0/lib/std/fs/Dir.zig#L2390-L2396):

> Berhati-hatilah terhadap race condition [Time-Of-Check-Time-Of-Use](https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use) saat menggunakan fungsi ini.
> Misalnya, alih-alih memeriksa apakah sebuah file ada lalu membukanya, cukup buka saja dan tangani error file not found.
13 changes: 13 additions & 0 deletions src/id-ID/01-05-iterate-dir.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
.title = "Iterasi direktori",
.date = "2026-04-29 11:20",
.author = "ZigCC",
.layout = "section.shtml",
---
Iterasi direktori

Tersedia metode `walk` yang praktis untuk tujuan ini, yang akan menelusuri direktori secara iteratif.

[]($code.siteAsset('src/01-05.zig').language('zig'))

Urutan entri sistem file yang dikembalikan tidak ditentukan. Jika ada persyaratan untuk urutan pengembalian entri, seperti abjad atau kronologis waktu, maka urutkan sesuai kebutuhan. Jika tidak, biarkan dalam urutan aslinya yang tidak diurutkan.
11 changes: 11 additions & 0 deletions src/id-ID/02-01-sha-digest.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
.title = "Menghitung digest SHA-256 dari sebuah file",
.date = "2026-04-29 11:23",
.author = "ZigCC",
.layout = "section.shtml",
---
Menghitung digest SHA-256 dari sebuah file

Terdapat banyak implementasi algoritma kriptografi di std, `sha256`, `md5` didukung secara langsung.

[]($code.siteAsset('src/02-01.zig').language('zig'))
14 changes: 14 additions & 0 deletions src/id-ID/02-02-pbkdf2.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
.title = "Salt dan hash sebuah password menggunakan PBKDF2",
.date = "2026-04-29 11:25",
.author = "ZigCC",
.layout = "section.shtml",
---
Salt dan hash sebuah password menggunakan PBKDF2

Gunakan [`std.crypto.pwhash.pbkdf2`] untuk melakukan hashing pada password yang diberi salt menggunakan HMAC-SHA256. Ketika sudah produksi, salt harus dihasilkan secara acak menggunakan [`std.Io.randomSecure`].

[]($code.siteAsset('src/02-02.zig').language('zig'))

[`std.crypto.pwhash.pbkdf2`]: https://ziglang.org/documentation/0.16.0/std/#std.crypto.pwhash.pbkdf2
[`std.Io.randomSecure`]: https://ziglang.org/documentation/0.16.0/std/#std.Io.randomSecure
14 changes: 14 additions & 0 deletions src/id-ID/02-03-argon2.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
.title = "Salt dan hash sebuah password dengan Argon2",
.date = "2026-04-29 11:29",
.author = "ZigCC",
.layout = "section.shtml",
---
Salt dan hash sebuh password dengan Argon2

Program Zig ini menghasilkan kunci kriptografi dari password dan salt menggunakan algoritma hashing kata sandi Argon2id. Program ini menggunakan [std.crypto.pwhash.argon2] untuk melakukan hashing pada password yang diberi salt, di mana salt dihasilkan menggunakan [`std.Io.randomSecure`].

[]($code.siteAsset('src/02-03.zig').language('zig'))

[`std.crypto.pwhash.argon2`]: https://ziglang.org/documentation/0.16.0/std/#std.crypto.pwhash.argon2
[`std.Io.randomSecure`]: https://ziglang.org/documentation/0.16.0/std/#std.Io.randomSecure
15 changes: 15 additions & 0 deletions src/id-ID/03-01-elapsed-time.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
.title = "Mengukur waktu yang berlalu antara dua bagian kode",
.date = "2026-04-29 11:30",
.author = "ZigCC",
.layout = "section.shtml",
---

[`Io.Clock`] menyediakan stempel waktu monoton melalui `Io.Clock.awake.now(io)`. Memanggil `durationTo` pada stempel waktu akan mengembalikan `Duration` yang telah berlalu dalam nanodetik.

Untuk tidur, gunakan [`Io.sleep`] dengan nilai `Duration`.

[]($code.siteAsset('src/03-01.zig').language('zig'))

[`Io.Clock`]: https://ziglang.org/documentation/0.16.0/std/#std.Io.Clock
[`Io.sleep`]: https://ziglang.org/documentation/0.16.0/std/#std.Io.sleep
26 changes: 26 additions & 0 deletions src/id-ID/04-01-tcp-server.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
.title = "Listen ke port TCP/IP yang tidak digunakan",
.date = "2026-04-29 11:31",
.author = "ZigCC",
.layout = "section.shtml",
---

Dalam contoh ini, port ditampilkan di konsol, dan program akan
mendengarkan hingga ada permintaan. Menggunakan `IpAddress` dengan `.loopback(0)` akan menetapkan
port acak.

[]($code.siteAsset('src/04-01.zig').language('zig'))

Saat program dimulai, coba uji seperti ini:

```bash
echo "hello zig" | nc localhost <port>
```

Secara default, program mendengarkan dengan IPv4. Jika Anda menginginkan IPv6, gunakan
`net.IpAddress{ .ip6 = .loopback(0) }` sebagai gantinya.

(Dan hubungkan ke sesuatu seperti `ip6-localhost`, tergantung pada cara
mesin Anda diatur.)

Bagian selanjutnya akan menunjukkan cara terhubung ke server ini menggunakan kode Zig.
16 changes: 16 additions & 0 deletions src/id-ID/04-02-tcp-client.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
.title = "TCP Client",
.date = "2026-04-29 11:38",
.author = "ZigCC",
.layout = "section.shtml",
---

Dalam contoh ini, kami mendemonstrasikan pembuatan klien TCP untuk terhubung ke server dari bagian sebelumnya.

Anda dapat menjalankannya menggunakan `zig build run-04-02 -- <port>`.

[]($code.siteAsset('src/04-02.zig').language('zig'))

Secara default, program terhubung dengan IPv4. Jika Anda menginginkan IPv6, gunakan
`::1` sebagai pengganti `127.0.0.1`, ganti `net.IpAddress.parseIp4` dengan
`net.IpAddress.parseIp6`.
20 changes: 20 additions & 0 deletions src/id-ID/04-03-udp-echo.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
---
.title = "UDP Echo",
.date = "2026-04-29 11:40",
.author = "ZigCC",
.layout = "section.shtml",
---

Mirip dengan contoh server TCP, program ini akan mendengarkan pada alamat IP dan port yang ditentukan, tetapi kali ini untuk datagram UDP. Jika data diterima,
data tersebut akan dikembalikan ke alamat pengirim.

Meskipun `std.Io.net` sebagian besar berfokus pada abstraksi untuk TCP (sejauh ini), kita masih dapat
menggunakan pemrograman soket untuk berkomunikasi melalui UDP.

[]($code.siteAsset('src/04-03.zig').language('zig'))

Setelah menjalankan program, uji sebagai berikut dengan `nc`, menggunakan flag `-u` untuk UDP:

```bash
echo "hello zig" | nc -u localhost <port>
```
17 changes: 17 additions & 0 deletions src/id-ID/05-01-http-get.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
.title = "GET",
.date = "2026-04-29 11:43",
.author = "ZigCC",
.layout = "section.shtml",
---

Mengurai URL yang diberikan dan membuat permintaan HTTP GET sinkron
dengan [`request`]. Mencetak status dan header [`Response`] yang diperoleh.

> Catatan: Karena dukungan HTTP masih dalam tahap awal, disarankan untuk menggunakan [libcurl](https://curl.se/libcurl/c/) untuk tugas yang kompleks.
> Dan jika buffer tidak cukup, akan mengembalikan `error.HttpHeadersOverSize`

[]($code.siteAsset('src/05-01.zig').language('zig'))

[`request`]: https://ziglang.org/documentation/0.16.0/std/src/std/http/Client.zig.html#L992
[`Response`]: https://ziglang.org/documentation/0.16.0/std/src/std/http/Client.zig.html#L322
16 changes: 16 additions & 0 deletions src/id-ID/05-02-http-post.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
.title = "POST",
.date = "2026-04-29 11:45",
.author = "ZigCC",
.layout = "section.shtml",
---

Mengurai URL yang diberikan dan membuat permintaan HTTP POST sinkron
dengan [`request`]. Mencetak status [`Response`] yang diperoleh, dan data yang diterima dari server.

> Catatan: Karena dukungan HTTP masih dalam tahap awal, disarankan untuk menggunakan [libcurl](https://curl.se/libcurl/c/) untuk tugas yang kompleks.

[]($code.siteAsset('src/05-02.zig').language('zig'))

[`request`]: https://ziglang.org/documentation/0.16.0/std/src/std/http/Client.zig.html#L992
[`Response`]: https://ziglang.org/documentation/0.16.0/std/src/std/http/Client.zig.html#L322
54 changes: 54 additions & 0 deletions src/id-ID/05-03-http-server-std.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
.title = "http.Server - std",
.date = "2026-04-29 11:46",
.author = "ZigCC",
.layout = "section.shtml",
---

Implementasi dasar `http.Server` telah diperkenalkan sejak Zig 0.12.0.

Untuk setiap koneksi, kami membuat thread baru untuk menanganinya, di `accept` thread tersebut akan:
1. Pertama, ia menggunakan `defer` untuk memastikan koneksi ditutup saat dikembalikan.

2. Kemudian menginisialisasi server HTTP untuk mulai mengurai permintaan.
3. Untuk setiap permintaan, pertama-tama kami memeriksa apakah permintaan tersebut dapat ditingkatkan ke WebSocket.

- Jika berhasil, panggil `serveWebSocket`, jika tidak, panggil `serverHTTP`
Comment thread
yumanuralfath marked this conversation as resolved.

[]($code.siteAsset('src/05-03.zig').language('zig'))

## Tes

Untuk HTTP, kita bisa menggunakan `curl`:
```bash
curl -v localhost:8080
```
Hasilnya akan seperti ini:
```bash
< HTTP/1.1 200 OK
< content-length: 32
< custom header: custom value
<
Hello World from Zig HTTP server
```

Untuk WebSocket, kita bisa menggunakan konsol di `Developer Tools` browser Anda:

```js
var webSocket = new WebSocket('ws://localhost:8080');
webSocket.onmessage = function(data) { console.log(data); }
```
Kemudian kita bisa mengirim pesan seperti ini:
```js
webSocket.send('abc')
```

[websocket-client]($image.siteAsset('images/websocket-client.webp'))

Lihat [Menulis aplikasi klien WebSocket - Web API | MDN](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications) untuk detailnya.

## Catatan
Implementasi standar menunjukkan kinerja yang sangat buruk. Jika Anda berencana melampaui eksperimen dasar, pertimbangkan untuk menggunakan pustaka alternatif seperti:
- <https://github.com/karlseguin/http.zig>
- <https://github.com/zigzap/zap>
- <https://github.com/mookums/zzz>
12 changes: 12 additions & 0 deletions src/id-ID/06-01-rand.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
.title = "Penghasil nilai acak",
.date = "2026-04-29 11:49",
.author = "ZigCC",
.layout = "section.shtml",
---

Menghasilkan angka acak menggunakan [`std.Random.IoSource`], yang menyediakan generator angka acak yang aman secara kriptografis yang didukung oleh antarmuka I/O sistem.

[]($code.siteAsset('src/06-01.zig').language('zig'))

[`std.Random.IoSource`]: https://ziglang.org/documentation/0.16.0/std/#std.Random.IoSource
18 changes: 18 additions & 0 deletions src/id-ID/07-01-spawn.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
---
.title = "Membuat thread sementara",
.date = "2026-04-29 11:51",
.author = "ZigCC",
.layout = "section.shtml",
---

Contoh ini menggunakan [`std.Thread`] untuk pemrograman konkuren dan paralel.
[`std.Thread.spawn`] membuat thread baru untuk menghitung hasilnya.

Contoh ini membagi array menjadi dua bagian dan melakukan pekerjaan di thread yang terpisah.

> Catatan: Untuk memastikan thread `t1` telah selesai ketika pembuatan `t2` gagal, kita menggunakan `defer t1.join()` segera setelah membuat `t1`.

[]($code.siteAsset('src/07-01.zig').language('zig'))

[`std.Thread`]: https://ziglang.org/documentation/0.16.0/std/#std.Thread
[`std.Thread.spawn`]: https://ziglang.org/documentation/0.16.0/std/#std.Thread.spawn
13 changes: 13 additions & 0 deletions src/id-ID/07-02-shared-data.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
.title = "Berbagi data antara dua thread",
.date = "2026-04-29 11:52",
.author = "ZigCC",
.layout = "section.shtml",
---

Ketika kita ingin mengubah data yang dibagi antar thread, [`Mutex`] (**Mut**ually **ex**clusive flag) harus digunakan untuk menyinkronkan thread, karena jika tidak, hasilnya bisa tidak terduga.

[]($code.siteAsset('src/07-02.zig').language('zig'))
Jika kita menghapus perlindungan Mutex, hasilnya kemungkinan besar akan kurang dari 30.000.

[`Mutex`]: https://ziglang.org/documentation/0.16.0/std/#std.Io.Mutex
15 changes: 15 additions & 0 deletions src/id-ID/07-03-threadpool.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
.title = "Thread pool",
.date = "2026-04-29 11:56",
.author = "ZigCC",
.layout = "section.shtml",
---

Thread pool menyelesaikan dua masalah berbeda:
1. Biasanya memberikan peningkatan performa saat menjalankan tugas asinkron dalam jumlah besar, karena berkurangnya overhead pemanggilan per tugas, dan
2. Menyediakan cara untuk membatasi dan mengelola sumber daya, termasuk thread, yang digunakan saat menjalankan sekumpulan tugas.


Dalam contoh ini, kita membuat 10 tugas menggunakan `Io.Group`, dan memanggil `await` untuk menunggu semuanya selesai.

[]($code.siteAsset('src/07-03.zig').language('zig'))
17 changes: 17 additions & 0 deletions src/id-ID/07-04-run-once.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
.title = "Run Once",
.date = "2026-04-29 11:57",
.author = "ZigCC",
.layout = "section.shtml",
---


`std.once` telah dihapus di Zig 0.16. Di sini kita mengimplementasikan semantik "jalankan tepat sekali" secara manual menggunakan protokol atomik tiga-status:

- **0 (idle)** – belum ada thread yang memulai pekerjaan.
- **1 (running)** – satu thread berhasil merebut kesempatan dan sedang menjalankan tugasnya.
- **2 (done)** – tugas telah selesai; semua thread dapat langsung kembali.

Ini memastikan suatu fungsi hanya dijalankan tepat satu kali, terlepas dari berapa banyak thread yang mencoba memanggilnya. Berguna untuk pola singleton dan operasi inisialisasi sekali pakai.

[]($code.siteAsset('src/07-04.zig').language('zig'))
12 changes: 12 additions & 0 deletions src/id-ID/08-01-cpu-count.smd
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
.title = "Memeriksa jumlah core CPU logis",
.date = "2026-04-29 11:58",
.author = "ZigCC",
.layout = "section.shtml",
---

Menampilkan jumlah core CPU logis pada mesin yang sedang berjalan menggunakan [`std.Thread.getCpuCount`].

[]($code.siteAsset('src/08-01.zig').language('zig'))

[`std.Thread.getCpuCount`]: https://ziglang.org/documentation/0.16.0/std/#std.Thread.getCpuCount
Loading
Loading