从 10 进制转换为 31 进制(仅适用于选定的字符)

发布于 2024-08-08 05:16:08 字数 524 浏览 9 评论 0原文

我想将基数 10 的数字转换为基数 31

我只想使用这些字符:23456789abcdefghjkmnpqrstuvwxyz

如您所见,排除了 5 个字符(我不需要这些):1 0 ol i

我现在的功能如下,但当然它不起作用。当输入 2 时,它输出 4。tenTo31(2) 的输出应该是 2

function tenTo31($num)
{
    $out   = "";
    $alpha = "23456789abcdefghjkmnpqrstuvwxyz";

    while($num > 30)
    {
        $r = $num % 31;
        $num = floor($num / 31) - 1;
        $out = $alpha[$r] . $out;
    }

    return $alpha[$num] . $out;
}

关于如何使其工作有什么想法吗?

I'd like to convert base 10 numbers to base 31

I would like to use only these characters: 23456789abcdefghjkmnpqrstuvwxyz

As you can see, 5 characters are excluded (i don't need these): 1 0 o l i

The function I have now is below but of course it doesn't work. When 2 is input it outputs 4. The output for tenTo31(2) should be 2

function tenTo31($num)
{
    $out   = "";
    $alpha = "23456789abcdefghjkmnpqrstuvwxyz";

    while($num > 30)
    {
        $r = $num % 31;
        $num = floor($num / 31) - 1;
        $out = $alpha[$r] . $out;
    }

    return $alpha[$num] . $out;
}

Any ideas on how to make this work?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情徒 2024-08-15 05:16:08

这是对你想要什么的盲目猜测:

$alpha = "yz23456789abcdefghjkmnpqrstuvwx";

This is a blind guess at what you want:

$alpha = "yz23456789abcdefghjkmnpqrstuvwx";
油焖大侠 2024-08-15 05:16:08

有一个内置函数可以将一种基数转换为另一种基数,base_convert()。字母表是固定的,但您可以使用 strtr() 将这些数字替换为您自己的数字。

“tenTo31(2) 的输出应该是 2”:一种可能性是再次使“2”成为第三个符号。

function tenTo31($num) {
  static $from = "0123456789abcdefghijklmnopqrstu";
  static $to   = "yz23456789abcdefghjkmnpqrstuvwx";
  return strtr(base_convert($num, 10, 31), $from, $to);
}

for($i=0; $i<31; $i++) {
 echo $i, '=', tenTo31($i), ' | ';
 if ( 9===$i%10 ) echo "\n";
}

打印

0=y | 1=z | 2=2 | 3=3 | 4=4 | 5=5 | 6=6 | 7=7 | 8=8 | 9=9 | 
10=a | 11=b | 12=c | 13=d | 14=e | 15=f | 16=g | 17=h | 18=j | 19=k | 
20=m | 21=n | 22=p | 23=q | 24=r | 25=s | 26=t | 27=u | 28=v | 29=w | 
30=x |

编辑:
要将 base(31) 数字转换回十进制,您首先必须反转转换 (strtr),然后调用 base_convert(.., 31, 10)。您可以将基数(31) 的转换与基数(31) 的转换合并到一个函数中。

function convert_ten_31($num, $numIsDecimal) {
  static $default = "0123456789abcdefghijklmnopqrstu";
  static $symbols = "yz23456789abcdefghjkmnpqrstuvwx";

  if ( $numIsDecimal ) {
   return strtr(base_convert($num, 10, 31), $default, $symbols);
  }
  else {
   return base_convert(strtr($num, $symbols, $default), 31, 10);
  } 
}

// testing
for($i=0; $i<10000; $i++) {
 $x = convert_ten_31($i, true);
 $x = convert_ten_31($x, false);

 if ( $i!==(int)$x ) {
  var_dump($i, $x);
  die;
 }
}
echo 'done.';

您也可以轻松地自己编写一个像 base_convert() 这样的函数,该函数将符号作为参数,从而拥有一个灵活的函数来代替 tenTo30()、tenTo31()、tenTo32() 等。

There's a built-in function for converting from one base to another, base_convert(). The alphabet is fixed, but you can use strtr() to replace those digits with your own.

"The output for tenTo31(2) should be 2": One possibility is to make '2' the third symbol again.

function tenTo31($num) {
  static $from = "0123456789abcdefghijklmnopqrstu";
  static $to   = "yz23456789abcdefghjkmnpqrstuvwx";
  return strtr(base_convert($num, 10, 31), $from, $to);
}

for($i=0; $i<31; $i++) {
 echo $i, '=', tenTo31($i), ' | ';
 if ( 9===$i%10 ) echo "\n";
}

prints

0=y | 1=z | 2=2 | 3=3 | 4=4 | 5=5 | 6=6 | 7=7 | 8=8 | 9=9 | 
10=a | 11=b | 12=c | 13=d | 14=e | 15=f | 16=g | 17=h | 18=j | 19=k | 
20=m | 21=n | 22=p | 23=q | 24=r | 25=s | 26=t | 27=u | 28=v | 29=w | 
30=x |

edit:
To convert the base(31) number back to decimal you first have to reverse the translation (strtr) and then call base_convert(.., 31, 10). You can combine the conversion from and to base(31) in a single function.

function convert_ten_31($num, $numIsDecimal) {
  static $default = "0123456789abcdefghijklmnopqrstu";
  static $symbols = "yz23456789abcdefghjkmnpqrstuvwx";

  if ( $numIsDecimal ) {
   return strtr(base_convert($num, 10, 31), $default, $symbols);
  }
  else {
   return base_convert(strtr($num, $symbols, $default), 31, 10);
  } 
}

// testing
for($i=0; $i<10000; $i++) {
 $x = convert_ten_31($i, true);
 $x = convert_ten_31($x, false);

 if ( $i!==(int)$x ) {
  var_dump($i, $x);
  die;
 }
}
echo 'done.';

It's also easily possible to write a function like base_convert() yourself that take the symbols as parameter and thus having one flexible function instead of tenTo30(), tenTo31(), tenTo32(), ....

吹泡泡o 2024-08-15 05:16:08

您没有使用 1 和 0 字符,编号系统中的第一个数字是 2,这意味着 2 相当于基数 10 中的 0。3 相当于基数 10 中的 1,4 相当于基数 10 中的 2。

You aren't using the 1 and 0 characters, the first digit in your numbering system is 2 meaning 2 is the equivalent of 0 in base 10. 3 is equivalent to 1 in base 10 and 4 is equivalent to 2 in base 10.

-柠檬树下少年和吉他 2024-08-15 05:16:08

为什么要在 32 之前学习模块?您应该使用 %31 和 /31。在基数 10 中,我们使用的是 10 的模块,所以应该在基数 31 中。但是如果我们忘记了这一点,我认为你的逻辑是正确的。我不明白为什么使用你的“修改后的数字”,10 进制的 2 等于 31 进制的 4。

Why are you taking modules by 32? You should use %31 and /31. In base 10 we are using modules by 10, so should be in base 31. But if we forget about this, I think your logic is correct. I can't understand why 2 in base 10 is equal to 4 in base 31 using your "modified digits".

情话难免假 2024-08-15 05:16:08

虽然我鼓励您继续使用算法进行学习练习,但请考虑使用 base_convert 如果您只是需要完成工作。

While I'd encourage you to continue along with your algorithm for the learning exercise, consider using base_convert if you just need to get the job done.

伴梦长久 2024-08-15 05:16:08

根据 http://www.crockford.com/wrmg/base32.html 似乎是:

function symbolToEncode ($num) {
    $out   = "";
    static $alpha = "0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=U";

    while ($num >= 37) {
        $r = $num % 37;
        $num = floor ($num / 37);
        $out = $out . $alpha[$r];
    }

    return $out . $alpha[$num];
}

function decodeToEncode ($str) {
  static $from = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*~=$";
  static $to   = "0123456789ABCDEFGH1JK1MN0PQRSTUVWXYZABCDEFGH1JK1MN0PQRSTUVWXYZ*~=$";
  return strtr ($str, $from, $to);
}

尽管显然真正的挑战是编写一个encodeToSymbol() 函数。我并不是真正的 PHP 专家(字符串中的 $ 可能需要以某种方式转义 - 提示?),所以我将把它留给其他人。

The mapping according to http://www.crockford.com/wrmg/base32.html appears to be:

function symbolToEncode ($num) {
    $out   = "";
    static $alpha = "0123456789ABCDEFGHJKMNPQRSTVWXYZ*~$=U";

    while ($num >= 37) {
        $r = $num % 37;
        $num = floor ($num / 37);
        $out = $out . $alpha[$r];
    }

    return $out . $alpha[$num];
}

function decodeToEncode ($str) {
  static $from = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ*~=$";
  static $to   = "0123456789ABCDEFGH1JK1MN0PQRSTUVWXYZABCDEFGH1JK1MN0PQRSTUVWXYZ*~=$";
  return strtr ($str, $from, $to);
}

Though clearly the real challenge is to write a encodeToSymbol() function. I am not really a PHP expert (my $'s in the strings probably needs to be escaped somehow -- hints?), so I will leave that to others.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文