content: private final static String ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
  
  public static void main(String[] args) {
      Assert("Test 01", ValidateBitcoinAddress("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"), true);
      Assert("Test 02", ValidateBitcoinAddress("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62j"), false);
      Assert("Test 03", ValidateBitcoinAddress("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nK9"), true);
      Assert("Test 04", ValidateBitcoinAddress("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62X"), false);
      Assert("Test 05", ValidateBitcoinAddress("1ANNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"), false);
      Assert("Test 06", ValidateBitcoinAddress("1A Na15ZQXAZUgFiqJ2i7Z2DPU2J6hW62i"), false);
      Assert("Test 07", ValidateBitcoinAddress("BZbvjr"), false);
      Assert("Test 08", ValidateBitcoinAddress("i55j"), false);
      Assert("Test 09", ValidateBitcoinAddress("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62!"), false);
      Assert("Test 10", ValidateBitcoinAddress("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62iz"), false);
      Assert("Test 11", ValidateBitcoinAddress("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62izz"), false);
      Assert("Test 12", ValidateBitcoinAddress("1Q1pE5vPGEEMqRcVRMbtBK842Y6Pzo6nJ9"), false);
      Assert("Test 13", ValidateBitcoinAddress("1AGNa15ZQXAZUgFiqJ2i7Z2DPU2J6hW62I"), false);
  }
  
  public static boolean ValidateBitcoinAddress(String addr) {
      if (addr.length() < 26 || addr.length() > 35) return false;
      byte[] decoded = DecodeBase58(addr, 58, 25);
      if (decoded == null) return false;
  
      byte[] hash = Sha256(decoded, 0, 21, 2);
  
      return Arrays.equals(Arrays.copyOfRange(hash, 0, 4), Arrays.copyOfRange(decoded, 21, 25));
  }
  
  private static byte[] DecodeBase58(String input, int base, int len) {
      byte[] output = new byte[len];
      for (int i = 0; i < input.length(); i++) {
          char t = input.charAt(i);
  
          int p = ALPHABET.indexOf(t);
          if (p == -1) return null;
          for (int j = len - 1; j > 0; j--, p /= 256) {
              p += base * (output[j] & 0xFF);
              output[j] = (byte) (p % 256);
          }
          if (p != 0) return null;
      }
  
      return output;
  }
  
  private static byte[] Sha256(byte[] data, int start, int len, int recursion) {
      if (recursion == 0) return data;
  
      try {
          MessageDigest md = MessageDigest.getInstance("SHA-256");
          md.update(Arrays.copyOfRange(data, start, start + len));
          return Sha256(md.digest(), 0, 32, recursion - 1);
      } catch (NoSuchAlgorithmException e) {
          return null;
      }
  }
  
  public static void Assert(String name, boolean value, boolean expected) {
      if (value ^ expected)
          throw new Error("Test " + name + " failed");
      else
          System.out.println(name + " passed");
  }
  