phpstringmathreversedata-conversion

Translate integer to letters and vice versa (e.g. 0 = "A", 26 = "AA", 27 = "AB")


So I have this function:

function toAlpha($data){
    $alphabet =   array('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');
    $alpha_flip = array_flip($alphabet);
    if($data <= 25){
      return $alphabet[$data];
    }
    elseif($data > 25){
      $dividend = ($data + 1);
      $alpha = '';
      $modulo;
      while ($dividend > 0){
        $modulo = ($dividend - 1) % 26;
        $alpha = $alphabet[$modulo] . $alpha;
        $dividend = floor((($dividend - $modulo) / 26));
      } 
      return $alpha;
    }
}

which given a number converts it into character and it works fine

but then I also want a reverse function of this that given any output of this function, return the exact input that was put in to produce that output and I tried this:

function toNum($data){
$alphabet =   array('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');
    $alpha_flip = array_flip($alphabet);
  if(strlen($data) == 1){
          return (isset($alpha_flip[$data]) ? $alpha_flip[$data] : FALSE);
        }
        else if(strlen($data) > 1){
          $num = 1;
          for($i = 0; $i < strlen($data); $i++){
            if(($i + 1) < strlen($data)){
              $num *= (26 * ($alpha_flip[$data[$i]] + 1));
            }
            else{
              $num += ($alpha_flip[$data[$i]] + 1);
            }
          }
          return ($num + 25);
        }
}

but it's not working properly...toAlpha(728) is producing 'aba' but toNum('aba') is producing 1378 rather than 728...

What did I do wrong? How can I fix the reverse function so that it works properly?


Solution

  • I don't understand at all the logic you're trying to use in that function. What you're trying to do seems very strange (why does 'a' map to zero and yet 'aa' maps to 26?), but this appears to work. (You will want to use some more test cases, I only checked that it gives the correct output for the case 'aba'.)

    function toNum($data) {
        $alphabet = array( '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'
                           );
        $alpha_flip = array_flip($alphabet);
        $return_value = -1;
        $length = strlen($data);
        for ($i = 0; $i < $length; $i++) {
            $return_value +=
                ($alpha_flip[$data[$i]] + 1) * pow(26, ($length - $i - 1));
        }
        return $return_value;
    }