title: why my code doesn't generate the same OTP like google authenticator?
body: <p>someone know why this TOTP code doesn't generate the same OTP like google  authenticator???
  the SHA1-HASH function is working well, it's just the final OTP that dosen't generated correct. I tried to check everything and I couldn't find where my mistake. can someone help please? this code supposed to be a very basic code to generate TOTP.</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;math.h&gt;
  #include &lt;time.h&gt;
  #include &quot;SHA_1.h&quot;
  
  void xor (char *arr, int length, int value)
  {
      int i;
      for (i = 0; i &lt; length; i++)
          arr[i] ^= value;
  }
  
      int main()
  {
      int CT, i, j;
      long int T;
      const int T0 = 0, Tx = 30;
      const char o_pad = 0x5C, i_pad = 0x36;
      unsigned char result[20];
      unsigned char counter[8];
      unsigned char secretKey[64] = &quot;abcdefghijklmnop&quot;;
  
      // HMAC
      unsigned char block[128];
      unsigned char inner_key[64];
      unsigned char outter_key[64];
  
      //HOTP
      int offset;
      long int truncatedHash;
      long int finalOTP;
  
      T = (long int)(time(NULL));
      CT = floor((T - T0) / Tx);
  
      for (i = strlen(counter)-1; i &gt;= 0; i--)
      {
          counter[i] = (unsigned char)(CT &amp; 0xFF);
          CT &gt;&gt;= 8;
      }
  
      // HMAC
  
      // Inner Key = K xor 0x36
      memset(inner_key, 0, 64);
      memcpy(inner_key, secretKey, strlen(secretKey));
      xor(inner_key, sizeof(inner_key), i_pad);
  
      // Outter Key = K xor 0x5C
      memset(outter_key, 0, 64);
      memcpy(outter_key, secretKey, strlen(secretKey));
      xor(outter_key, sizeof(outter_key), o_pad);
  
      // Hash Inner
      memset(block, 0, sizeof(block));
      for (i = 0; i &lt; 64; i++)
      {
          block[i] = inner_key[i];
      }
      for (i = 0; i &lt; strlen(counter); i++)
      {
          block[i + 64] = counter[i];
      }
      SHA1_HASH(block, strlen(block), result);
  
  
      // Hash Outter
      memset(block, 0, sizeof(block));
      for (i = 0; i &lt; 64; i++)
      {
          block[i] = outter_key[i];
      }
      for (i = 0; i &lt; strlen(result); i++)
      {
          block[i + 64] = result[i];
      }
      SHA1_HASH(block, strlen(block), result);
  
      offset = result[19] &amp; 0x0f;
  
      truncatedHash = ((result[offset] &amp; 0x7f) &lt;&lt; 24) | ((result[offset + 1] &amp; 0xff) &lt;&lt; 16) | ((result[offset + 2] &amp; 0xff) &lt;&lt; 8) | (result[offset + 3] &amp; 0xff);
  
      finalOTP = (truncatedHash % (long int)pow(10, 6));
  
      printf(&quot;%d&quot;, finalOTP);
  
      return 0;
  }
  </code></pre>
  <hr />
  <p><em><strong>EDITED</strong></em></p>
  <hr />
  <p>My SHA_1 code:</p>
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  
  // circular rotate function
  unsigned int S(int n, unsigned int word)
  {
      return ((word &lt;&lt; n) | (word &gt;&gt; (32 - n)));
  }
  
  // constant K
  const unsigned int K[4] = {
      0x5A827999,
      0x6ED9EBA1,
      0x8F1BBCDC,
      0xCA62C1D6};
  
  // H values
  unsigned int H[5] = {
      0x67452301,
      0xEFCDAB89,
      0x98BADCFE,
      0x10325476,
      0xC3D2E1F0};
  
  void SHA1_HASH(unsigned char *input,int input_length, char *output)
  {
      // Variabels Declaration
      unsigned char M[128];
      unsigned int W[80];
      unsigned int j, i, TEMP, A, B, C, D, E;
      unsigned char HH[20], temp_HH[20];
      int M_size;
  
      // clear M
      memset(M, 0, sizeof(M));
  
      // Copy the messege into M
      strcpy(M, input);
  
      // add the length of the messege to the end of M
      if (input_length &gt; 55)
      {
          M[127] = (unsigned char)(input_length * 8);
          M[126] = (unsigned char)(input_length * 8 &gt;&gt; 8);
          M_size = 2;
      }
      else
      {
          M[63] = (unsigned char)(input_length * 8);
          M[62] = (unsigned char)(input_length * 8 &gt;&gt; 8);
          M_size = 1;
      }
  
      // set bit '1' after the messege
      M[input_length] |= (unsigned char)0x80;
      
      for(j=0; j&lt;M_size; j++){
      //init Words in W[0] - W[15]
      for (i = 0; i &lt; 16; i++)
      {
          W[i] = ((unsigned int)M[(4 * i)+(64*j)] &lt;&lt; 24) | ((unsigned int)M[(1 + (4 * i))+(64*j)] &lt;&lt; 16) | ((unsigned int)M[(2 + (4 * i))+(64*j)] &lt;&lt; 8) | ((unsigned int)M[(3 + (4 * i))+(64*j)]);
      }
  
      for (i = 16; i &lt; 80; i++)
      {
          W[i] = S(1, W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]);
      }
  
      //start of the SHA-1 alghoritem
  
      A = H[0];
      B = H[1];
      C = H[2];
      D = H[3];
      E = H[4];
  
      for (i = 0; i &lt; 20; i++) // round 1
      {
          TEMP = S(5, A) + ((B &amp; C) | ((~B) &amp; D)) + E + W[i] + K[0];
          E = D;
          D = C;
          C = S(30, B);
          B = A;
          A = TEMP;
      }
  
      for (i = 20; i &lt; 40; i++) //round 2
      {
          TEMP = S(5, A) + (B ^ C ^ D) + E + W[i] + K[1];
          E = D;
          D = C;
          C = S(30, B);
          B = A;
          A = TEMP;
      }
  
      for (i = 40; i &lt; 60; i++) //round 3
      {
          TEMP = S(5, A) + ((B &amp; C) | (B &amp; D) | (C &amp; D)) + E + W[i] + K[2];
          E = D;
          D = C;
          C = S(30, B);
          B = A;
          A = TEMP;
      }
  
      for (i = 60; i &lt; 80; i++) //round 4
      {
          TEMP = S(5, A) + (B ^ C ^ D) + E + W[i] + K[3];
          E = D;
          D = C;
          C = S(30, B);
          B = A;
          A = TEMP;
      }
  
      H[0] += A;
      H[1] += B;
      H[2] += C;
      H[3] += D;
      H[4] += E;
      }
  
      sprintf(HH, &quot;%x&quot;, H[0]);
      for (i = 1; i &lt; 5; i++)
      {
          sprintf(temp_HH, &quot;%x&quot;, H[i]);
          strcat(HH, temp_HH);
      }
      // end of SHA-1 alghoritem
  
      // return the algoritem result
      strcpy(output, HH);
  }
  
  </code></pre>