diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..822895d828941cf6cc60f68aaac31b7dfd40462b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+myzip0
+myunzip0
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..f1e3ca95a2c8efeeceae703a15d25fb8fef20608
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,7 @@
+all : myzip0 myunzip0
+
+myzip0 : myzip0.c
+	cc myzip0.c -o myzip0
+
+myunzip0 : myunzip0.c
+	cc myunzip0.c -o myunzip0
\ No newline at end of file
diff --git a/myzip0.c b/myzip0.c
new file mode 100644
index 0000000000000000000000000000000000000000..4c2bd23877f10177dfbea0cc7fe26f366bff7798
--- /dev/null
+++ b/myzip0.c
@@ -0,0 +1,131 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+#include <assert.h>
+
+const uint32_t BUFFER_SIZE = 1024;
+
+int write_u8(FILE *file, const uint8_t v)
+{
+    return fwrite(&v, sizeof(uint8_t), 1, file);
+}
+
+int write_u16(FILE *file, const uint16_t v)
+{
+    return fwrite(&v, sizeof(uint16_t), 1, file);
+}
+
+int write_u32(FILE *file, const uint32_t v)
+{
+    return fwrite(&v, sizeof(uint32_t), 1, file);
+}
+
+int copy_file_to_file(FILE *input, FILE *output, uint32_t bytes)
+{
+    uint8_t buffer[BUFFER_SIZE];
+    uint32_t bytes_written = 0;
+
+    for (uint32_t start = 0; start < bytes; start += BUFFER_SIZE)
+    {
+        uint32_t remaining_bytes = bytes - start;
+        uint32_t copy_this_iter = (remaining_bytes < BUFFER_SIZE) ?
+                        remaining_bytes : BUFFER_SIZE;
+
+        fread(buffer, 1, copy_this_iter, input);
+        bytes_written += fwrite(buffer, 1, copy_this_iter, output);
+    }
+
+    return bytes_written;
+}
+
+int main(int argc, char *argv[])
+{
+    if (argc != 3)
+    {
+        fprintf(stderr, "Usage: %s <output zip filename> <input file filename>\n", argv[0]);
+        return 1;
+    }
+
+    const char *output_file_name = argv[1];
+    const char *input_file_name = argv[2];
+    FILE *input_file = fopen(input_file_name, "r");
+    FILE *output_file = fopen(output_file_name, "w");
+
+    if (input_file == NULL)
+    {
+        fprintf(stderr, "Could not open \"%s\"\n", input_file_name);
+        return 1;
+    }
+
+    if (output_file == NULL)
+    {
+        fprintf(stderr, "Could not open \"%s\"\n", output_file_name);
+        return 2;
+    }
+
+
+
+    fseek(input_file, 0, SEEK_END);
+    uint32_t input_file_size = ftell(input_file);
+    fseek(input_file, 0, SEEK_SET);
+
+    /* (1) LOCAL FILE RECORD */
+    write_u32(output_file, 0x04034b50); /* local file signature */
+    write_u16(output_file, 20); /* extract version */
+    write_u16(output_file, 0); /* general purpose flag */
+    write_u16(output_file, 0); /* compression method */
+    write_u16(output_file, 0); /* last mod file time */
+    write_u16(output_file, 0); /* last mod file date */
+    write_u32(output_file, 0xDEADBEEF); /* crc */
+    write_u32(output_file, input_file_size); /* compressed file size */
+    write_u32(output_file, input_file_size); /* uncompressed file size */
+    write_u16(output_file, strlen(input_file_name)); /* file name len */
+    write_u16(output_file, 0); /* extra field length */
+    fputs(input_file_name, output_file); /* file name */
+    /* extra field */
+    /* copy input file to output */
+    copy_file_to_file(input_file, output_file, input_file_size);
+
+    uint32_t central_directory_start = ftell(output_file);
+
+    /* (2) CENTRAL DIRECTORY RECORD */
+    write_u32(output_file, 0x02014b50); /* central directory signature */
+    write_u8 (output_file, 30); /* specification version */
+    write_u8 (output_file, 65); /* made by */
+    write_u16(output_file, 20); /* extract version */
+    write_u16(output_file, 0); /* general purpose bit flag */
+    write_u16(output_file, 0); /* compression method */
+    write_u16(output_file, 0); /* last mod file time */
+    write_u16(output_file, 0); /* last mod file date */
+    write_u32(output_file, 0xdeadbeef); /* crc */
+    write_u32(output_file, input_file_size); /* compressed file size */
+    write_u32(output_file, input_file_size); /* uncompressed file size */
+    write_u16(output_file, strlen(input_file_name)); /* file name length */
+    write_u16(output_file, 0); /* extra field length */
+    write_u16(output_file, 0); /* file comment length */
+    write_u16(output_file, 0); /* disk number start */
+    write_u16(output_file, 1); /* internal file attributes */
+    write_u32(output_file, 1); /* external file attributes */
+    write_u32(output_file, 0); /* offset of local header */
+    fputs(input_file_name, output_file); /* file name */
+    /* extra field */
+    /* file comment */
+
+    uint32_t end_record_start = ftell(output_file);
+
+    /* (3) END OF CENTRAL DIRECTORY RECORD */
+    write_u32(output_file, 0x06054b50); /* end of central dir signature */
+    write_u16(output_file, 0); /* number of this disk */
+    write_u16(output_file, 0); /* number of the start disk */
+    write_u16(output_file, 1); /* total number of entries on this disk */
+    write_u16(output_file, 1); /* total number of entries */
+    write_u32(output_file, end_record_start - central_directory_start); /* size of central directory record */
+    write_u32(output_file, central_directory_start); /* offset of start of central directory */
+    write_u16(output_file, 0); /* .zip file comment length */
+    /* .zip file comment */
+
+    fclose(input_file);
+    fclose(output_file);
+    return 0;
+}
\ No newline at end of file