言語別、62進数<->10進数の変換スクリプトたち (R, Python, Java)

## 概要
言語別、62進数<->10進数の変換スクリプトたち

## 言語
- R 3.4.2
- Python 2.6.6
- Java(openjdk version "1.8.0_151")


## R
### Rのインストール

```
$ sudo yum -y install epel-release
$ sudo yum -y install R --enablerepo=epel
```

### スクリプト

```r:convert_decimal62.r
encode_decimal62 <- function(num, chars=c(0:9, letters, LETTERS)) {
    base <- length(chars)
    str <- NULL
    repeat {
        str <- c(chars[num %% base+1], str)
        num <- num %/% base
        if (num == 0) {
            break
        }
    }
    paste(str, collapse="")
}

decode_decimal62 <- function(str, chars=c(0:9, letters, LETTERS)) {
    base <- length(chars)
    str_list <- unlist(strsplit(str, split = ""))
    num <- 0
    for (char in str_list) {
        num <- num * base + which(chars == char) - 1
    }
    num
}

encode_decimal62(0)
encode_decimal62(12345)

decode_decimal62("0")
decode_decimal62("3d7")
```

実行

```
$ Rscript decode_decimal62.r
[1] "0"
[1] "3d7"
[1] 0
[1] 12345
```

## python

```py:convert_decimal62.py
alnum = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJELMNOPQRSTUVWXYZ"

def encode_decimal62(num, chars = alnum):
    base = len(chars)
    string = ""
    while True:
        string = chars[num % base] + string
        num = num // base
        if num == 0:
            break
    return string

def decode_decimal62(string, chars = alnum):
    base = len(chars)
    num = 0
    for char in string:
        num = num * base + chars.index(char)
    return num

print(encode_decimal62(0))
print(encode_decimal62(12345))

print(decode_decimal62('0'))
print(decode_decimal62('3d7'))
```

実行

```
$ python convert_decimal62.py
0
3d7
0
12345
```

## Java

```java:Decimal62Converter.java
import java.util.regex.Pattern;

public class Decimal62Converter {
    private static final String TABLE = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static final int BASE = 62;

    public static void main(String[] args) {
        System.out.println(encrypt(0));
        System.out.println(encrypt(12345));
        System.out.println(decrypt("0"));
        System.out.println(decrypt("3d7"));
    }

    /** concatenate integers
     * 
     * @param digits
     * @return string value of concatenated integers
     */
    public static long concatnateDigits(int... digits)
    {
        StringBuffer sb = new StringBuffer(digits.length);
        for(int digit: digits) {
            sb.append(digit);
        }
        return Long.parseLong(sb.toString());
    }
     
    /** convert integer to alphanumeric characters
     * 
     * @param number
     * @return encrypted string
     */
    public static String encrypt(long number)
    {
        StringBuffer sb = new StringBuffer();
        while(true) {
            sb.insert(0, TABLE.charAt((int)(number % BASE)));
            number = number / BASE;

            if (number == 0) {
                break;
            }
        }
        return sb.toString();
    }

    /** convert alphanumeric characters to integer
     * 
     * @param phrase
     * @return Integer converted from phrase.
     *         Return -1 if the phrase contains not convertible character.
     */
    public static long decrypt(String phrase)
    {
        // validation.
        // if the phrase has character other than in TABLE
        // return -1;
        if(Pattern.compile("[^" + TABLE + "]").matcher(phrase).find()) {
            return -1;
        }
        String reverse = new StringBuffer(phrase).reverse().toString();
        long decimal = 0;
        for(int i = 0; i < reverse.length(); i++) {
            int digit = TABLE.indexOf(reverse.charAt(i));
            decimal = (long) (decimal + digit * Math.pow(BASE, i));
        }
        return decimal;
    }
}
```

コンパイル

```
$ javac Decimal62Converter.java
```

実行

```
$ java Decimal62Converter
0
3d7
0
12345
```



## 参考
- [インフラ屋さんのためのR言語: 環境構築編](https://qiita.com/tomotagwork/items/5cd9362f386d330fe96a)
- [R で n 進数を 10 進数に変換する #rstatsj](https://qiita.com/hoxo_m/items/82ad2493f73d20648b1c)
- [Python練習帳 基数変換](http://php6.jp/python/2011/02/02/%E5%9F%BA%E6%95%B0%E5%A4%89%E6%8F%9B/)
- [Java で整数値を基数 62 の文字列に変換するには](http://tilfin.hatenablog.com/entry/20100622/1277176778)