62進数を取り扱ってみる

戻る

$ java -cp .. Spider.Samarium
10進数: 10000 → 62進数: 000002bI
10進数: 61 → 62進数: 0000000z
10進数: 62 → 62進数: 00000010

c=2     digit=2 order=2
c=b     digit=37        order=1
c=I     digit=18        order=0
"2bI" comes to be 10000
c=A     digit=10        order=2
c=z     digit=61        order=1
c=1     digit=1 order=0
"Az1" comes to be 42223
c=1     digit=1 order=0
"1" comes to be 1
c=1     digit=1 order=1
c=0     digit=0 order=0
"10" comes to be 62
c=z     digit=61        order=0
"z" comes to be 61
c=0     digit=0 order=1
c=z     digit=61        order=0
"0z" comes to be 61
Spider.SamariumUnsupportedCharacterException: (文字 - はサポートされていません!)
        at Spider.Samarium.getDecimalValue(Samarium.java:109)
        at Spider.Samarium.main(Samarium.java:157)

■以下ソース

package Spider;

public class Samarium {

    /**
         * 基数
         */
    static private final int NUMBER = 62;

    static private Character[] base = new Character[ NUMBER ];

    static {
        // from '0' to '9'
        for ( int i = 0;i < 10;i++ ) {
            base[ i + 0 ] = new Character( ( char ) ( 48 + i ) );
        }
        // from 'A' to 'Z'
        for ( int i = 0;i < 26;i++ ) {
            base[ i + 10 ] = new Character( ( char ) ( 65 + i ) );
        }
        // from 'a' to 'z'
        for ( int i = 0;i < 26;i++ ) {
            base[ i + 36 ] = new Character( ( char ) ( 97 + i ) );
        }
    }

    static private void dump() {
        for ( int i = 0;i < NUMBER;i++ ) {
            System.out.println( i + ": " + ( char ) base[ i ] );
        }
    }

    /**
         *  10進数を62進数に変換します
         *  @param  decimal 10進数 
         *  @param  length  ゼロパディングした全体の桁数
         *  @return 62進数で記述された文字列
         */
    static String convert( int decimal, int length ) {
        StringBuffer result = new StringBuffer();
        int mod = 0;
        // System.out.println( "decimal=" + decimal );

        // 基数で割っていきその余りを求めていく
        while ( decimal >= NUMBER ) {
            mod = decimal % NUMBER;
            // System.err.println( "mod=" + mod + ":" + (char)base[mod]);

            // 先頭にインサート
            result.insert( 0, ( char ) base[ mod ] );

            decimal = decimal / NUMBER;
        }
        // System.err.println( "rest=" + rest + ":" + (char)base[rest]);

        // 先頭にインサート
        result.insert( 0, ( char ) base[ decimal ] );

        // 先頭にゼロパディング
        while ( result.length() < length ) {
            result.insert( 0, "0" );
        }


        return result.toString();
    }

    /**
        *  62進数を10進数で表します
        *  10進数 = 62^n * d0 + 62^(n-1) * d1 + ... +  62^0 * dn  ( d[0-n] must be between 0 and 61 )
        *  @param  in 
        *  @return 10進数
        */
    static public long getDecimalValue( String in ) throws Exception {
        long longValue = 0;

        for ( int i = 0;i < in.length();i++ ) {
            int order = in.length() - i - 1;
            char c = in.charAt( i );

            int digit = 0;
            if ( c >= '0' && c <= '9' ) {
                digit = ( c - '0' );
            } else if ( c >= 'A' && c <= 'Z' ) {
                digit = ( c - 'A' + 10 );
            } else if ( c >= 'a' && c <= 'z' ) {
                digit = ( c - 'a' + 36 );
            } else {
                throw new SamariumUnsupportedCharacterException( "文字 " + c + " はサポートされていません!" );
            }

            System.err.println( "c=" + c + "\tdigit=" + digit + "\torder=" + order );

            longValue += digit * power( order );
        }

        return longValue;
    }

    /**
        *  基数62のべき乗を返します
        *  @param  order 桁数
        *  @return 10進数
        */
    static private long power( int order ) {
        long result = 1;
        for ( int i = 0;i < order;i++ ) {
            result *= NUMBER;
        }
        return result;
    }

    /**
        *  単体試験用のメインメソッド
        *  @param  なし
        *  @return なし
        */
    static public void main( String[] args ) {

        // this can be verified by calculating the following way
        // ( 2*62*62 + 37*62 + 18 ) comes to be 10000

        System.out.println( "10進数: 10000 → 62進数: " + convert( 10000, 8 ) );
        System.out.println( "10進数: 61 → 62進数: " + convert( 61, 8 ) );
        System.out.println( "10進数: 62 → 62進数: " + convert( 62, 8 ) );
        System.out.println( );

        try {
            System.out.println( "\"2bI\" comes to be " + getDecimalValue( "2bI" ) );
            System.out.println( "\"Az1\" comes to be " + getDecimalValue( "Az1" ) );
            System.out.println( "\"1\" comes to be " + getDecimalValue( "1" ) );
            System.out.println( "\"10\" comes to be " + getDecimalValue( "10" ) );
            System.out.println( "\"z\" comes to be " + getDecimalValue( "z" ) );
            System.out.println( "\"0z\" comes to be " + getDecimalValue( "0z" ) );

            // SamariumUnsupportedCharacterExceptionを拾えるか確認する
            System.out.println( "\"-34\" comes to be " + getDecimalValue( "-34" ) );
        } catch ( Exception e ) {
            e.printStackTrace();
        }

    }
}

/*
       Character a = new Character( 'a' );
       System.out.println( "a: " + Integer.valueOf( a ) ); // displays 97
 
       Character A = new Character( 'A' );
        System.out.println( "A: " + Integer.valueOf( A ) ); // diplays 65
 
       Character zero = new Character( '0' );
       System.out.println( "zero: " + Integer.valueOf( zero ) ); // displays 48
 
       Character one = new Character( ( char ) 49 );
       System.out.println( "one: " + Integer.valueOf( one ) );	// displays 49
       System.out.println( "one: " + "'" + one + "'" );	// displays '1'
 
       for ( int i = 0;i < 26;i++ ) {
           System.out.println( i + ": " + new Character((char)(65+i)));
       }
*/



package Spider;

// $Id: Samarium.html,v 1.1 2009/06/22 16:11:55 kishi Exp kishi $

public class SamariumUnsupportedCharacterException extends Exception {

    public SamariumUnsupportedCharacterException( String errmsg ) {
        super( "(" + errmsg + ")" );
    }
}


inserted by FC2 system