1) First optimization has been made at the beginning: source: #define PSIZE 8 modified in: #define PSIZE 0x0008 This to make things clear even before the pre-processor starts to ask itself what are the default behaviors. b) Depending on the platform, we could also have: 0x00000008 ---------------------------------------------[ new paragraph 2) source: char *pwd = "crackMe2"; modified in: const char *pwd = "crackMe2"; Keyword 'const' added. This to avoid - in perhaps further implementations - some one distractedly overwrites the value. ---------------------------------------------[ new paragraph 2a) The same instruction needs also a restyling, like: from: const char *pwd = "crackMe2"; to: const static char *pwd = "crackMe2"; This to avoid - if the execution goes out of scope, like calling a function and coming back - that the value could be randomly altered. ---------------------------------------------[ new paragraph 3) Added the zeroing of the array buf. This to prevent any Murphy' Law accident after the scanf() function. On whose use too I have comments. Needs: #include ---------------------------------------------[ new paragraph 4) The scanf() function has some odds. It can't distinguish between integers and literals; it stops counting the input at the first space; it has problem with commas, etc. There are some workarounds. A solution is to use getchar() and scan the whole input string; another one is to hook the keyboard interrupts, and so on. I'll use getchar() - (that saves me developing time, *winks). We need a buffer in here: char ch; ---------------------------------------------[ new paragraph 5) Loop improvement. Instead of: while(buf[k] != '\0'){ use: while( ch != '\n' && k < PSIZE ) This will affect the sequence of the instructions. - It makes sure to take exactly PSIZE chars. - This method eventually allows to accept strings with spaces. ---------------------------------------------[ new paragraph 6) With the actual logic, buf doesn't have a null terminator. So we increase its size by 1: char buf[PSIZE + 1]; This, together with: memset( buf, '\0', sizeof(buf)); makes sure that buf is null terminated. For any further use. ---------------------------------------------[ new paragraph 7) This paragraph is a proof-of-concept. For security purpose, in the source the following instruction has been changed: const static char *pwd = "crackMe2"; to: const static char *pwd = "dsbdlNf3"; This to prevent some one opens the executable with an hex editor, and the password is there, on a fine sight. The user - however - will keep on introducing "crackMe2". As I said this was just a proof-of-concept. In the real world I would use any salted function.