<?php
/**
* @author: Jörg Reinholz, fastix WebDesign & Consult, Kassel - http://www.fastix.org/
* @version: 1.0.4
* @licence: https://code.fastix.org/lizenz.php
**/

class numberSystem
{
    protected $arChars = false;
    protected $hash = false;

    function __construct($var='niceReadable32') {
        switch (true) {
            case ( is_array($var) ):
                return setChars( $var );
            case ( 'bin' == $var || 'binär' == $var ):
                $this -> setChars (  array('0','1') );
                break;
            case ( 'alphabet' == $var || 'alpha' == $var ):
                $this -> setChars ('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ');
                break;
            case ( 'ascii_33_126' == $var || 'ascii_visible' == $var ):
                $ar = array();
                for ($i=33; $i<127; $i++) { $ar[] = chr($i); }
                $this -> setChars($ar);
                break;
            case( 'niceReadable32' == $var ):
                $this -> setChars ( array('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','J','K','L','M','N','P','R','S','T','U','V','W','X','Y','Z') );
                break;
            case( 'decObusfacted' == $var || 'wuerfel' == $var ):
                $this -> setChars ( array('0','9','8','7','1','2','3','5','4','6') );
                break;
            default:
                $this -> setChars ( $var );
                break;
        }
        return true;
    }

    public function getChars() {
        return $this -> arChars;
    }

    public function getHash() {
        return $this -> hash;
    }

    public function setChars($arr) {
        if (! is_array( $arr ) ) {
            $arr = preg_split('//u', $arr, -1, PREG_SPLIT_NO_EMPTY);
        }
        if (2 <= count($arr) ) {
            $test = array_unique($arr);
            if ( $test == $arr) {
                $this -> arChars = $arr;
                $this -> hash = $this -> mkHash($arr);
                return count($arr);
            } else {
                trigger_error ( 'class: numberSystem, function: setChars :: Der übergebene Array ist nicht unique', E_USER_ERROR );
            }
        } else {
            trigger_error ( 'class: numberSystem, function: setChars :: Es wurde kein Array übergeben oder der Array hat weniger als zwei Elemente', E_USER_ERROR );
        }
        return false;
    }

    private function mkHash( $arr ) {
        $i=0;
        foreach ( $arr as $element ) {
            $hash[$element] = $i++;
        }
        return $hash;
    }

    public function getDec( $str ) {
        $number = 0;
        $length = strlen($str);
        for ( $i = $length; $i > 0; $i-- ) {
            $inv  = $length - ( $i );
            $char = $str[( $i-1 )];
            if ( ! isset ( $this -> hash[$char] ) ) {
                trigger_error ( 'class: numberSystem, function: getNumberFromString :: Das Zeichen "'.$char.'" ist in der verwendeten Symboltabelle nicht enthalten', E_USER_ERROR );
                return false;
            }
            $number = $number +  pow( count($this -> hash), $inv ) * ( $this -> hash[$char] );
        }
        return $number;
    }

    function getString( $int ) {
        # gibt die Zahl aus dem beliebigen Zahlensystem (String)  zurück
        if ( $int > PHP_INT_MAX ) {
            trigger_error ( 'class: numberSystem, function: getString :: Es wurde eine zu große Zahl ('.$int.') übergeben. Maximum ist '. PHP_INT_MAX , E_USER_ERROR );
        }
        if ( 0 == $int ) {
            return $this -> arChars[$int];
        }
        $length    = count($this -> arChars);
        $str       = '';
        $positions = 0;
        while ( pow( $length, $positions ) <= $int ) {
                $positions++;
        }
        for ($i = $positions; $i > 0; $i-- ) {
                $potenz = pow( $length, $i-1 );
                $pos = floor( $int / $potenz );
                $int = $int % $potenz;
                $str = $str . $this -> arChars[$pos];
        }
        return $str;
    }
}