美文网首页
10进制与16,32,62进制相互转换

10进制与16,32,62进制相互转换

作者: BenjaminCool | 来源:发表于2020-01-07 22:22 被阅读0次

/*

  • Copyright (c) 2010 Ant Kutschera, maxant
  • The code below is free software: you can redistribute it and/or modify
  • it under the terms of the Lesser GNU General Public License as published by
  • the Free Software Foundation, either version 3 of the License, or
  • (at your option) any later version.
  • The code in this file is distributed in the hope that it will be useful,
  • but WITHOUT ANY WARRANTY; without even the implied warranty of
  • MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  • Lesser GNU General Public License for more details.
  • You should have received a copy of the Lesser GNU General Public License
  • along with Foobar. If not, see http://www.gnu.org/licenses/.
    */

package uk.co.maxant.util;

import java.math.BigInteger;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**

  • allows you to convert a whole number into a compacted representation of that number,

  • based upon the dictionary you provide. very similar to base64 encoding, or indeed hex

  • encoding.
    */
    public class BaseX {

    /**

    • contains hexadecimals 0-F only.
      */
      public static final char[] DICTIONARY_16 =
      new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

    /**

    • contains only alphanumerics, in capitals and excludes letters/numbers which can be confused,
    • eg. 0 and O or L and I and 1.
      */
      public static final char[] DICTIONARY_32 =
      new char[]{'1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','J','K','M','N','P','Q','R','S','T','U','V','W','X','Y','Z'};

    /**

    • contains only alphanumerics, including both capitals and smalls.
      */
      public static final char[] DICTIONARY_62 =
      new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z'};

    /**

    • contains alphanumerics, including both capitals and smalls, and the following special chars:
    • +"@*#%&/|()=?'~[!]{}-:.,; (you might not be able to read all those using a browser!
      /
      public static final char[] DICTIONARY_89 =
      new char[]{'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','+','"','@','
      ','#','%','&','/','|','(',')','=','?','~','[',']','{','}','$','-','
      ','.',':',',',';','<','>'};

    protected char[] dictionary;

    /**

    • create an encoder with the given dictionary.
    • @param dictionary the dictionary to use when encoding and decoding.
      */
      public BaseX(char[] dictionary){
      this.dictionary = dictionary;
      }

    /**

    • creates an encoder with the {@link #DICTIONARY_62} dictionary.
    • @param dictionary the dictionary to use when encoding and decoding.
      */
      public BaseX(){
      this.dictionary = DICTIONARY_62;
      }

    /**

    • tester method.
      */
      public static void main(String[] args) {
      String original = "123456789012345678901234567890";
      System.out.println("Original: " + original);
      BaseX bx = new BaseX(DICTIONARY_62);
      String encoded = bx.encode(new BigInteger(original));
      System.out.println("encoded: " + encoded);
      BigInteger decoded = bx.decode(encoded);
      System.out.println("decoded: " + decoded);
      if(original.equals(decoded.toString())){
      System.out.println("Passed! decoded value is the same as the original.");
      }else{
      System.err.println("FAILED! decoded value is NOT the same as the original!!");
      }
      }

    /**

    • encodes the given string into the base of the dictionary provided in the constructor.

    • @param value the number to encode.

    • @return the encoded string.
      */
      public String encode(BigInteger value) {

      List<Character> result = new ArrayList<Character>();
      BigInteger base = new BigInteger("" + dictionary.length);
      int exponent = 1;
      BigInteger remaining = value;
      while(true){
      BigInteger a = base.pow(exponent); //16^1 = 16
      BigInteger b = remaining.mod(a); //119 % 16 = 7 | 112 % 256 = 112
      BigInteger c = base.pow(exponent - 1);
      BigInteger d = b.divide(c);

       //if d > dictionary.length, we have a problem. but BigInteger doesnt have
       //a greater than method :-(  hope for the best. theoretically, d is always 
       //an index of the dictionary!
       result.add(dictionary[d.intValue()]);
       remaining = remaining.subtract(b); //119 - 7 = 112 | 112 - 112 = 0
      
       //finished?
       if(remaining.equals(BigInteger.ZERO)){
           break;
       }
      
       exponent++;
      

      }

      //need to reverse it, since the start of the list contains the least significant values
      StringBuffer sb = new StringBuffer();
      for(int i = result.size()-1; i >= 0; i--){
      sb.append(result.get(i));
      }
      return sb.toString();
      }

    /**

    • decodes the given string from the base of the dictionary provided in the constructor.

    • @param str the string to decode.

    • @return the decoded number.
      */
      public BigInteger decode(String str) {

      //reverse it, coz its already reversed!
      char[] chars = new char[str.length()];
      str.getChars(0, str.length(), chars, 0);

      char[] chars2 = new char[str.length()];
      int i = chars2.length -1;
      for(char c : chars){
      chars2[i--] = c;
      }

      //for efficiency, make a map
      Map<Character, BigInteger> dictMap = new HashMap<Character, BigInteger>();
      int j = 0;
      for(char c : dictionary){
      dictMap.put(c, new BigInteger("" + j++));
      }

      BigInteger bi = BigInteger.ZERO;
      BigInteger base = new BigInteger("" + dictionary.length);
      int exponent = 0;
      for(char c : chars2){
      BigInteger a = dictMap.get(c);
      BigInteger b = base.pow(exponent).multiply(a);
      bi = bi.add(new BigInteger("" + b));
      exponent++;
      }

      return bi;

    }

}

相关文章

  • 10进制与16,32,62进制相互转换

    /* Copyright (c) 2010 Ant Kutschera, maxant The code belo...

  • js的进制转换

    js的进制转换, 分为2进制,8进制,10进制,16进制之间的相互转换, 我们直接利用 对象.toString()...

  • 进制转换

    2进制 , 8进制 , 10进制 , 16进制 , 介绍 及 相互转换 及 快速转换的方法 为什么要使用进制数 数...

  • java——进制

    进制转换 10进制十进制(逢10进1)是我们最常用的一种数位进制方式。 10进制和2进制可以相互转换,举例如下: ...

  • 程序员的数学1-数学思维 读书笔记(上)

    第1章 0的故事——无即是有 介绍了10进制、2进制,2进制与10进制之间的相互转换方法; 按位计数法; 指数法则...

  • js颜色进制之间的转换

    十进制、十六进制、RGBA颜色值之间的相互转换 10进制转rgba rgb转16进制 16进制转10进制 完整代码...

  • python 的进制转换

    十进制, 二进制相互转换 十进制转换为二进制 二进制转换为十进制 十进制, 八进制相互转换 十进制转换为八进制 八...

  • Java开发中常用的工具类

    一、16进制与10进制转换

  • Flutter 进制转换

    10进制转换位16进制 16进制转换位10进制

  • Android 常用数据转换

    有的时候忙着项目特别容易忘事,所以特此记录 进制转换 简单转换 可以看到其他进制之间相互转换,是先转为10进制,然...

网友评论

      本文标题:10进制与16,32,62进制相互转换

      本文链接:https://www.haomeiwen.com/subject/mapdactx.html