From 829c20fc3fcd7ee9555095f23bf3fb19f70fbb35 Mon Sep 17 00:00:00 2001 From: Lucas Pedeutour <1+lucas@noreply.localhost> Date: Mon, 11 May 2026 15:54:11 +0000 Subject: [PATCH] =?UTF-8?q?T=C3=A9l=C3=A9verser=20les=20fichiers=20vers=20?= =?UTF-8?q?"/"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Who robbed Thibouvre _.html | 3105 +++++++++++++++++++++++++++++++++++ assets.tar.gz | Bin 0 -> 1334982 bytes 2 files changed, 3105 insertions(+) create mode 100644 Who robbed Thibouvre _.html create mode 100644 assets.tar.gz diff --git a/Who robbed Thibouvre _.html b/Who robbed Thibouvre _.html new file mode 100644 index 0000000..788d3b1 --- /dev/null +++ b/Who robbed Thibouvre _.html @@ -0,0 +1,3105 @@ + + +
1.0.2 2026-02-16 10:42 2026-02-23 10:42 submit-* (limit: 3 per week) archi-* (limit: 2 per hour) epita-prepa-computer-science-prog-103-p-05-2030-firstname.lastname
+├── Who_robbed_Thibouvre
+│ ├── fundamentals
+│ │ ├── basic_read
+│ │ │ └── basic_read.c
+│ │ ├── basic_write
+│ │ │ └── basic_write.c
+│ │ ├── common_streams
+│ │ │ └── common_streams.c
+│ │ ├── count
+│ │ │ └── count.c
+│ │ ├── filter
+│ │ │ └── filter.c
+│ │ ├── hidden_message
+│ │ │ └── hidden_message.c
+│ │ ├── my_cp
+│ │ │ └── my_cp.c
+│ │ ├── my_grep
+│ │ │ └── my_grep.c
+│ │ ├── parser
+│ │ │ └── parser.c
+│ │ ├── print_lines
+│ │ │ └── print_lines.c
+│ │ └── write_format
+│ │ └── write_format.c
+│ └── proficiencies
+│ ├── decoder
+│ │ └── decoder.c
+│ ├── get_data
+│ │ └── get_data.c
+│ ├── save_data
+│ │ └── save_data.c
+│ └── scavenger_hunt
+│ └── scavenger_hunt.c
+├── .gitignore
+└── README
+firstname.lastname with your login. .gitignore file is mandatory. Tests folder. .gitignore file:*.a
+*.lib
+*.o
+*.obj
+*.out
+
+.idea/
+*~
+*.DotSettings.user
+string.h and stdio.h with man. fundamentals/basic_read/basic_read.c <stdio.h> library.fopen, fread, fwrite, and fclose (the f prefix simply stands for file).stdio library, do not forget to include it.man pages."mode" parameter. We will learn it later, just set it to the string "r" for now.int open_close(const char *filename); int main()
+{
+ int a = open_close("does_exist.txt");
+ int b = open_close("does_not_exist.txt");
+ printf("%d %d\n", a, b); // 0 1
+
+ return 0;
+}
+ char array of size n + 1, using malloc. The + 1 is mandatory if we need to add a null character after the resulting string.n characters, from the file, to the array, and store how many characters were read, into a variable m. It is required as it can be less than n if we reach the end of the file. m.fread(3) man page!int read_n_bytes(const char *filename, size_t n); /*
+$ cat does_exist.txt
+Hey, as you can see, this file is not empty and therefore you can open it, read it, and close it!
+*/
+
+int main()
+{
+ int a = read_n_bytes("does_exist.txt", 32);
+ printf(" | %d\n", a);
+ /* Expected:
+ Hey, as you can see, this file i
+ | 0
+ */
+
+ int b = read_n_bytes("does_not_exist.txt", 5);
+ printf(" | %d\n", b);
+ /* Expected:
+ | 1
+ */
+
+ return 0;
+}
+ int read_bytes(const char *filename); /*
+$ cat does_exist
+Hey, as you can see, this file is not empty and therefore you can open it, read it, and close it!
+*/
+
+int main()
+{
+ int a = read_bytes("does_exist.txt");
+ printf("--> Return code: %d\n", a);
+ /* Expected:
+ Hey, as you can see, this file is not empty and therefore you can open it, read it, and close it!
+ --> Return code: 0
+ */
+
+ int b = read_bytes("does_not_exist.txt");
+ printf("--> Return code: %d\n", b);
+ /* Expected:
+ --> Return code: 1
+ */
+
+ return 0;
+}
+ fundamentals/basic_write/basic_write.c "r", which just allows you to open the file for reading purpose. Now, you want to write on it, and even create the file if it does not exist.fopen(3) man page, and use the appropriate mode.fputc function to put a char into a file.fopen the right path.git push a lot, even without any tag, just in case.int write_one_by_one(char *filename, const char *text); int main()
+{
+ // does_exist.txt contains: "something which will be replaced"
+ int a = write_one_by_one("does_exist.txt", "Hello World!");
+ // does_exist.txt contains: "Hello World!"
+
+ // does_not_exist.txt... does not exist.
+ int b = write_one_by_one("does_not_exist.txt", "Now I exist");
+ // does_not_exist.txt... now exists and contains: "Now I exist"
+
+ printf("%d %d\n", a, b); // 0 0
+ // The opening should succeed as it creates the file if needed
+ // However it can fail if the file's access is forbidden
+
+ return 0;
+}
+ fputc call, you summon a system call, which is highly expensive for your poor CPU.fprintf function instead. It can write the entire string in only one syscall!fprintf(3) man page.int write_all_in_one(char *filename, const char *text); int main()
+{
+ // does_exist.txt contains: "Hello World!"
+ int a = write_all_in_one("does_exist.txt", "What a good day!");
+ // does_exist.txt contains: "What a good day!"
+
+ // still_not_yet_exist.txt... does not exist.
+ int b = write_all_in_one("still_not_yet_exist.txt", "Now I exist");
+ // still_not_yet_exist.txt... now exists and contains: "Now I exist"
+
+ printf("%d %d\n", a, b); // 0 0
+ // The opening should succeed as it creates the file if needed
+ // However it can fail if the file's access is forbidden
+
+ return 0;
+}
+ fundamentals/print_lines/print_lines.c > Line content for each line.getline function.getline function.lineptr is a result pointer.getline finds a \n, it will set the string that follows - which is the delimited field - into a string pointer (char **) given as parameter.n is another result pointer.lineptr contains the resulting string, well this parameter contains the resulting length of the string.lineptr, you need to pass a reference as parameter (int *).stream is the file stream.fopen.int print_lines(const char *filename); int main()
+{
+ print_lines("example.txt");
+ /* Expected:
+ > First line
+ > Second line
+ > Third line
+ > and so on
+ >
+ > ^^^ Even empty lines ^^^
+ */
+
+ return 0;
+}
+ fundamentals/my_cp/my_cp.c src to another one at dest.int my_cp(const char *src, const char *dest); int main()
+{
+ /*
+ example.txt <-- Create a copy of me!
+ trashy.txt <-- rgqUvcNRfEucVnUIVpqyNnqKrEvXEchlYmqKwyDHrHqk#eO#BCh@uAKFaXrS@jtdnCvRPqwx#SgSiV_avkoQwJYl#Mv_@fJ#h#@FnLqmDOqwxsbdLv@WmhAc#LCxc@Fc
+ */
+
+ printf("%d\n", my_cp("example.txt", "trashy.txt")); // 0
+ printf("%d\n", my_cp("new_file.txt", "example.txt")); // 1
+ printf("%d\n", my_cp("example.txt", "new_file.txt")); // 0
+
+ /*
+ example.txt <-- Create a copy of me!
+ trashy.txt <-- Create a copy of me!
+ new_file.txt <-- Create a copy of me!
+ */
+
+ return 0;
+}
+ fundamentals/count/count.c
> characters: [NUMBER OF CHARACTERS]
> words: [NUMBER OF WORDS]
> lines: [NUMBER OF LINES]
'\n' counts as a character.' ', '\t', '\n', or the end of the file.'\n'.int count(const char *filename); int main()
+{
+ return count("example.txt"); // <-- return 0, because example.txt exists
+ /* Expected:
+ > characters: 2030
+ > words: 103
+ > lines: 5
+ */
+}
+ fundamentals/write_format/write_format.c fprintf to compute the result into a string automatically!printf one.int write_format(void *data, enum data_type type, char *filename); void * type.void *var; and you write int *var_as_int = var;, then var_as_int will be an integer pointer pointing to the same address as var.type parameter as an enum. It will tell you what is the type of the data.filename file.write_format.c file. We also give it below:enum data_type {
+ STRING,
+ INTEGER,
+ POINTER
+};
+ int main()
+{
+ char *str = "Write me!";
+ int integer = 42;
+ int *ptr = &integer;
+ /*
+ As you can see, we pass an integer pointer to the function.
+ This is because genericity only applies to pointers, so you cannot directly pass an integer as a parameter.
+ It also means that you will have to dereference it in order to retrieve its value.
+ */
+
+ write_format(str, STRING, "output.txt");
+ write_format(ptr, INTEGER, "output.txt");
+ write_format(ptr, POINTER, "output.txt");
+ /** output.txt should contain:
+ String: Write me!
+ Integer: 42
+ Pointer: 0x424242424242 // Unfortunately, it may not be the result you will get, but something similar
+ */
+
+ /* FLAG
+ Complete the function in order to print the password into output.txt.
+ */
+ size_t password[2] = { 7940247895376159821, 0 };
+ write_format(password, STRING, "output.txt");
+
+ return 0;
+}
+ fundamentals/filter/filter.c acc.acc.acc. acc is a multiple of , print the line.12345678910111211.3.5.7.9.0.1.2.2.6.10.14.18.0.2.4.2.6.1.5.9.0.2.4.2264165891012141, it does not end with a so we do not have to print it.int filter(char* filename); int main()
+{
+ /* example.txt
+ 1234567891011121
+ 1742909510526
+ */
+
+ int a = filter("example.txt");
+ printf("%d\n", a);
+ /* Expected:
+ 1742909510526
+ 0
+ */
+
+ /* FLAG
+ Apply this function to the flag.txt file, it will give you the suspect cards.
+ You should obtain exactly 5 results.
+ */
+ filter("flag.txt");
+
+ return 0;
+}
+ fundamentals/my_grep/my_grep.c grep shell command.grep is a very useful tool which allows you to fetch lines from a file, in which a given pattern is included inside.filename to read and expr, an expression that you will have to find as a substring in each line of the file.strstr function.int my_grep(char *filename, char *expr); int main()
+{
+ printf("\n%d\n", my_grep("example.txt", "word"));
+ /* Expected:
+ This line contains words.
+ And "words" contains "word".
+ word
+ 1
+ */
+
+ putchar('\n');
+
+ printf("%d\n", my_grep("example.txt", "eqlijgber")); // Returns 0
+ printf("%d\n", my_grep("empty_file.txt", "word")); // Returns 0
+ printf("%d\n", my_grep("inexisting_file.txt", "word")); // Returns 2
+
+ putchar('\n');
+
+ /* FLAG
+ Try "grepping" the flag.csv file, by the credit card numbers you found in
+ the previous flag.
+ Then, only keep those which booked several entries.
+ */
+ my_grep("flag.csv", "Put here the credit card numbers");
+ my_grep("flag.csv", "Put here the credit card numbers");
+ my_grep("flag.csv", "Put here the credit card numbers");
+ my_grep("flag.csv", "Put here the credit card numbers");
+ my_grep("flag.csv", "Put here the credit card numbers");
+
+ return 0;
+}
+ fundamentals/common_streams/common_streams.c FILE * are already opened by default.printf("...") call, it is in fact equivalent to: fprintf(stdout, "...").stdout, stderr and stdin.stdout is the default output location of your program. This is where you print all your testing messages with printf for example.stderr is another output location, but used for error messages. This is where your SEGV errors go for example.stdin is where the user can input something in your program.stdin, test if it matches a valid pattern, and:"Accepted: %s\n" in the stdout stream,"Error: %s\n" on the stderr, where %s is the line which failed the verification.[a-zA-Z0-9]+\.[a-zA-Z0-9]+.main() function.CTRL-D shortcut.stdin, and will be thus the stopping signal of your program.ENTER.$ ./common_streams # Write this and the following lines in the terminal.
+tom.nook
+Accepted: tom.nook
+.tomnook
+Error: .tomnook
+tomnook.
+Error: tomnook.
+tom.no.ok
+Error: tom.no.ok
+tomnook
+Error: tomnook
+
+Error:
+abc0.def1
+Accepted: abc0.def1
+<CTRL-D PRESSED, END OF FILE SENT>
+
+$ # You should be back with your usual prompt
+ fundamentals/hidden_message/hidden_message.c putchar instead of printf if you want to print only one character.getdelim function. It allows you to split a file stream into several strings.getline.int hidden_message(const char *filename, const char delim); int main()
+{
+ hidden_message("example.txt", ':'); // Must return 0.
+ // Must print nook
+
+ putchar('\n');
+
+ hidden_message("example.txt", ';'); // Must return 0.
+ // Must print: n
+ // Because no delimiter was found, so only the first character is printed
+
+ putchar('\n');
+
+ hidden_message("does_not_exist.txt", ':'); // Must return 1.
+ // Must not print anything
+
+ /* FLAG
+ Decode the given message to understand what it means
+ */
+ hidden_message("flag.txt", '~');
+
+ return 0;
+}
+ fundamentals/parser/parser.c Alice:42
+Bob:15
+SomethingAsText:123
+ atoi(3) man page.int parser(char *filename); int main()
+{
+ int a = parser("example.txt");
+ /* Expected:
+ SomethingAsText
+ 123
+ 60
+ */
+
+ //
+ int b = parser("empty.txt");
+ int c = parser("wrong_delimiter.txt");
+ int d = parser("wrong_number.txt");
+ int e = parser("does_not_exist.txt");
+ // Expected is nothing.
+
+ printf("%d %d %d %d %d\n", a, b, c, d, e);
+ // Expected: 0 2 2 2 1
+
+ /* FLAG
+ Let's read a file which contains every possible exit paths, assiociated with
+ its their discretion score. You want to get the most quiet among them.
+ */
+ parser("flag.txt");
+
+ return 0;
+}
+ proficiencies/get_data/get_data.c cat an executable file that you generated during your practicals, you will see that we cannot understand its content directly.filename parameter locates the file that you will have to read.block_size parameter gives you the length of blocks that you will have to read.length parameter indicates how many blocks you need to read.length first blocks of your file.malloc is defined in <stdlib.h>.NULL to indicate an error.void *get_data(char *filename, size_t block_size, size_t length); void * array.int main()
+{
+ void *a = get_data("example.txt", 1, 7);
+ printf("%.7s\n", (char *)a); // Prints: Example
+ free(a);
+
+ return 0;
+}
+ proficiencies/save_data/save_data.c void * pointer which is data to write in the filename file.int save_data(char *filename, size_t block_size, size_t length, void *data); int main()
+{
+ char *data = "This is readable text.";
+
+ save_data("new_file.txt", 1, 22, data);
+ printf("A new file has been created.\n");
+
+ /* FLAG
+ Analyze this serie of blood drops and convert it to DNA.
+ */
+ size_t t[7] = {
+ 7959390400869134169,
+ 8030516705471242340,
+ 4705773566797636194,
+ 3765928769057995296,
+ 4708850085609554226,
+ 3338648646059311435,
+ 5497845422045015598,
+ };
+ save_data("flag.txt", 1, 50, t);
+
+ return 0;
+}
+ proficiencies/scavenger_hunt/scavenger_hunt.c clue structure.scavenger_hunt.c file, you will see that it contains a letter and a next_offset integer.next_offset integer corresponds to the location of the next structure to consider.clue is a kind of linked-list structure that you may have already studied in your algoritm course.clue structure whose the next_offset field is -1.input file.output file (create it if needed).fopen function."rb", as you will read binary data, and for portability purpose.struct clue {
+ char letter;
+ long next_offset;
+};
+ int scavenger_hunt(char *input, char *output); int main()
+{
+ int a = scavenger_hunt("example.txt", "example.log");
+ int b = scavenger_hunt("does_not_exist.txt", "does_not_exist.log");
+
+ /* FLAG
+ You will apply the algorithm to the folder you shuffled, hoping that it will
+ give us the information sorted again...
+ */
+ int c = scavenger_hunt("flag.txt", "flag.log");
+
+ printf("%d %d %d\n", a, b, c);
+ // Expected: 0 1 0
+
+ /*
+ $ cat example.log
+ You found me!
+
+ $ cat flag.log
+ ???
+ */
+
+ return 0;
+}
+ proficiencies/decoder/decoder.c "rb" mode.int as parameter.char decode_block(int block); int main()
+{
+ printf("%c\n", decode_block(67307523));
+ /*
+ Binary representation is:
+ 0000 0100 | 0000 0011 | 0000 1000 | 0000 0011
+ Take the right-most byte: 0000 0011 = 3 in decimal
+
+ Perform a shift of 0000 0011 +8 = 3+8 = 11 to the right:
+ From: 0000 0100 | 0000 0011 | 0000 1000 | 0000 0011 -->
+ ---------------------------------------------
+ To: xxxx xxxx | xxx0 0000 | 1000 0000 | 0110 0001 (00000000011)
+ ^^^^ ^^^^ ^^^ ^^^^^^^^^^^
+ You can consider it as zeros. Useless to keep it
+
+ Now, the right-most byte is: 0110 0001 = 97 in decimal = 'a' in ASCII
+
+ So, expected result is:
+ a
+ */
+
+ return 0;
+}
+ int print_decoded_file(const char *filename); int main()
+{
+ print_decoded_file("example.txt");
+ /* Expected:
+ You are on the right way!
+ */
+
+ print_decoded_file("does_not_exist.txt");
+ // Nothing happens
+
+ /* FLAG
+ Decode this file, and you will discover the author of the biggest heist of
+ the last century...
+ */
+ // print_decoded_file("flag.txt"); // <-- Uncomment it...
+
+ return 0;
+}
+ [CTRL+-] or [CTR+SHIFT+-] to dezoom it.1.0.1 ] 2026-02-17 00:00:00 print_lines.c > print_lines: does not ask for a final line break anymore write_format.c > write_format: typo (there were two 'if it does not') 1.0.2 ] 2025-02-17 14:50:00 scavenger_hunt.c > scavenger_hunt: fix scavenger_hunt.h -> scavenger_hunt.c. _N!_d4SlsETg))y|Qm@
zw2|7ybOCzjSMq1J#n`PPF*o{K#C$d<5mB$)BIKVuEU&e3;(Gp0)=oYud5tL+@~=T2
z^1)jKg#-UyQZ0LT(;_yXyhF$v@1|VbS+)tgRZfp{q+;b1gUx M%JbQ^f`cj)$s;A8cno8Qpapk=&W;E2+lLLpEwPEN)5
zB^m8hrn|S1R$gO%)dd?ll1F K)@37Cf#5CjqM`L3Z&dQfnBAUsQnWhaGY%T(hTIC7oZ^yfMt6_pR
zT}(hv=qAQQt>iqCXP5@lpHW%HKF0T~7M07k%6McSM}K&VXDHR?q%;TL7P1WvxOw}2
zFOHsEtu>TtwKD0RTF-M%Zy*J=i8PjSA4Ox@jS*
zp-t#gY3t@>0eYo@xnuTY%E)aMpj)y*?vu>M**D};h6CJ|O1IO?I8&U$?YI|_S~_2R
z){-i{JAU6ibyzgELR^B6ORrtO%zhX9jJ-whru?2>PW*FAKxp}(RNA_JK}4;a#_9DJ
z(|eHt;>gR)W6?qS3REODtXmKdSPGdx&Tqi!U=}tnct{q@vC+-w0d}uozob@tgjB7Z
z;`UyOM7VH+kZ=73)gQZ-`6!A@?j#S$W=)Vsyy&B!M=QV+5`u88VDqlWvFOz}n~IqT
za`|6n>kTyJh^0f0mLq@Dz)9|vsObfCNQ7N=KvuGSg}BK2h~!CDO|aG}$wBOh`1clx
z&~j)GmpTc$f9f8<;wS7I!uPQGTS|a$pOJl>KojipU#N^2C)=Z=B}421sy6l!jwc?2
z+;}Uyo%G0l%C113a5I^+@?)Glg$eoN-=s#kpWx!dG69
T`?pH%D#`GSCxvo3?XLh^UH(%0IWR#x5=^kJ
z$iVZsH}w1_QQWds2y`Dw)ges%*NGZ84X+VvR3o+EzWSbBAq4M@5Q3ftNX$vMnrXnr
z%eo8UU4Ma}A28-N@*97OUSt(qgBg~1J73{gw=-s3Q=k4hzeNZIz9c_bRpu|vFdcdt
z*kR7^FgF2XPrZEo^}3%wcZUD&)H`G>E`WZ1-?*w5n}ahV(1Y!@{b8>X?{3x4h&8+u
zdsNM^p_i{U&~60Ri2~ooENvUHwhW}u1x&v#T$WW__w2-eSm)Q(sI!3{9M4EwT&^B;
z4#6Jxr&Z&aF+lJNf$K-Dh9fEQ;ZjMj_}9E;`4BE$furmPbGaHdVx@fg^N--`I9Dg)
zYITxRjrh
Gm`&OW<)KNaL-CCyX9(NFG5pqZcXj{^D2&ii_0OeVh~#N)jVrveerB5^sg-w3TA2
z{zfzuxLpf1DkboCO;2;wM54bJQ>Z&
zxp0)!*8P(_)%lZY>LRAk^H6u1Zg!dMpi4Bo=H*E!R6x86uzA?HPD%={(Dw=f#$@M}
zY^$eQ>#N~t;w^QDZ?)cEC{$|ghpNw)FUX75XlXJpzu=^3UXZ6w_q9~dhOf&EJZ$F7
zcI1gpp3IYU;Ai=Gs#eWv@m+=|kI-lIXVU!-sujU|xJD^ZCRlqVH8dJ{w)ZjfiX2ga
zcSWgkIUB>N#+9rfI!Nn`8i2^L85A06jpV+xlazVttU7B)j{5EXo6?rW)6Eyg#&H?v
zZke}C%6s3x!`lN|Gd^C3BIs2;CD|p9AuaJ_t(5h%rniZyF+ZB?7@^pZdA*aP7Wnp{
zIC_SRm_zY9e6GONc7R67XtO`ZSbpCs-d-|7aqLUxzb=BajcPrfuOZn-sS5oo$iDFY
z3LhPX#_oGkEA$WhyhoBA3aXR*(^bhAjVFUhmNC1a99pCANp^_|h1bmBXa~j8Y{ndG
zA&7Ly(uY*igR8Y^@I0!dZP;szw9fo_b*!f^M_=ntcFv=C3BQ|p{&g`LR%^vPukQ7)
zP=D|~ME&V5c_e8f#e~kwL&!pr1l9;buWR}%0_5nj-lRWIjVmrBCc4V;H#qnI@Ao`x
zU6HY43Ea_tb$@gvN8fk?jpE