title: google authenticator implementation java android
body: <p>i building an Android application that must have an Google authenticator code(Password) to access to it.
  the problem that i generate the serial code of 16 characters but when i try to write the validation code the application told me always that is wrong validation code... the time of the phone and the computer are the same so i donßt know why i does not work ...</p>
  
  <p>here some code that i used :</p>
  
  <pre><code>`
  //Base32.java
  private static final  Base32 INSTANCE = 
      new  Base32("ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"); // RFC 4668/3548
  
    static  Base32 getInstance() { 
      return INSTANCE;
    }
  
    // 32 alpha-numeric characters.
    private String ALPHABET;
    private char[] DIGITS;
    private int MASK;
    private int SHIFT;
    private HashMap&lt;Character, Integer&gt; CHAR_MAP;
  
    static final String SEPARATOR = "-";
  
    protected  Base32(String alphabet) {
      this.ALPHABET = alphabet;
      DIGITS = ALPHABET.toCharArray();
      MASK = DIGITS.length - 1;
      SHIFT = Integer.numberOfTrailingZeros(DIGITS.length);
      CHAR_MAP = new HashMap&lt;Character, Integer&gt;();
      for (int i = 0; i &lt; DIGITS.length; i++) {
        CHAR_MAP.put(DIGITS[i], i);
      }
    }
  
    public static byte[] decode(String encoded) throws DecodingException {
      return getInstance().decodeInternal(encoded);
    }
  
    protected byte[] decodeInternal(String encoded) throws DecodingException {
      // Remove whitespace and separators
      encoded = encoded.trim().replaceAll(SEPARATOR, "").replaceAll(" ", "");
      // Canonicalize to all upper case
      encoded = encoded.toUpperCase();
      if (encoded.length() == 0) {
        return new byte[0];
      }
      int encodedLength = encoded.length();
      int outLength = encodedLength * SHIFT / 8;
      byte[] result = new byte[outLength];
      int buffer = 0;
      int next = 0;
      int bitsLeft = 0;
      for (char c : encoded.toCharArray()) {
        if (!CHAR_MAP.containsKey(c)) {
          throw new DecodingException("Illegal character: " + c);
        }
        buffer &lt;&lt;= SHIFT;
        buffer |= CHAR_MAP.get(c) &amp; MASK;
        bitsLeft += SHIFT;
        if (bitsLeft &gt;= 8) {
          result[next++] = (byte) (buffer &gt;&gt; (bitsLeft - 8));
          bitsLeft -= 8;
        }
      }
      // We'll ignore leftover bits for now. 
      // 
      // if (next != outLength || bitsLeft &gt;= SHIFT) {
      //  throw new DecodingException("Bits left: " + bitsLeft);
      // }
      return result;
    }
  
    public static String encode(byte[] data) {
      return getInstance().encodeInternal(data);
    }
  
    protected String encodeInternal(byte[] data) {
      if (data.length == 0) {
        return "";
      }
  
      // SHIFT is the number of bits per output character, so the length of the
      // output is the length of the input multiplied by 8/SHIFT, rounded up.
      if (data.length &gt;= (1 &lt;&lt; 28)) {
        // The computation below will fail, so don't do it.
        throw new IllegalArgumentException();
      }
  
      int outputLength = (data.length * 8 + SHIFT - 1) / SHIFT;
      StringBuilder result = new StringBuilder(outputLength);
  
      int buffer = data[0];
      int next = 1;
      int bitsLeft = 8;
      while (bitsLeft &gt; 0 || next &lt; data.length) {
        if (bitsLeft &lt; SHIFT) {
          if (next &lt; data.length) {
            buffer &lt;&lt;= 8;
            buffer |= (data[next++] &amp; 0xff);
            bitsLeft += 8;
          } else {
            int pad = SHIFT - bitsLeft;
            buffer &lt;&lt;= pad;
            bitsLeft += pad;
          }
        }
        int index = MASK &amp; (buffer &gt;&gt; (bitsLeft - SHIFT));
        bitsLeft -= SHIFT;
        result.append(DIGITS[index]);
      }
      return result.toString();
    }
  
    @Override
    // enforce that this class is a singleton
    public Object clone() throws CloneNotSupportedException {
      throw new CloneNotSupportedException();
    }
  
    static class DecodingException extends Exception {
      public DecodingException(String message) {
        super(message);
      }
    }
  }`
  
  
  
  //CheckCode.java    
  ...public void onClick(View v) {
          String codeDigited=ed.getText().toString();
          Log.d("codeDigited", codeDigited);
          try {
              if(check_code(codeDigited, 0, 0)==true){
              Intent step = new Intent(this, GoogleAuthenticator.class);
              startActivity(step);
              }else{
               info.setText("passwords doesn't match! oh noes!");
              }
          } catch (InvalidKeyException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (NoSuchAlgorithmException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (DecodingException e) {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
      }
  
      private static boolean check_code(String secret, long code, long t)
              throws NoSuchAlgorithmException, InvalidKeyException, DecodingException {
          //Base32 codec = new Base32(secret);
          byte[] decodedKey = Base32.decode(secret);
  
          // Window is used to check codes generated in the near past.
          // You can use this value to tune how far you're willing to go.
          int window = 30;
          for (int i = -window; i &lt;= window; ++i) {
              long hash = verify_code(decodedKey, t + i);
  
              if (hash == code) {
                  System.out.println("right");
                  return true;
  
              }
          }
          System.out.println("OOOOOOOps codec.decode(secret): "+decodedKey.toString());
          // The validation code is invalid.
          return false;
      }
  
      private static int verify_code(byte[] key, long t)
              throws NoSuchAlgorithmException, InvalidKeyException {
          byte[] data = new byte[8];
          long value = t;
          for (int i = 8; i-- &gt; 0; value &gt;&gt;&gt;= 8) {
              data[i] = (byte) value;
          }
  
          SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1");
          Mac mac = Mac.getInstance("HmacSHA1");
          mac.init(signKey);
          byte[] hash = mac.doFinal(data);
  
          int offset = hash[20 - 1] &amp; 0xF;
  
          // We're using a long because Java hasn't got unsigned int.
          long truncatedHash = 0;
          for (int i = 0; i &lt; 4; ++i) {
              truncatedHash &lt;&lt;= 8;
              // We are dealing with signed bytes:
              // we just keep the first byte.
              truncatedHash |= (hash[offset + i] &amp; 0xFF);
          }
  
          truncatedHash &amp;= 0x7FFFFFFF;
          truncatedHash %= 1000000;
  
          return (int) truncatedHash;
      }
  </code></pre>
  
  <p>the codeDigited is the validation code i took from Google authentificator App
  but i don know why the code does not work </p>