bash에 내장된 함수만 사용하여 기본 10에서 임의의 기본 변환

bash에 내장된 함수만 사용하여 기본 10에서 임의의 기본 변환

지정된 문자 집합을 사용하여 숫자를 기본 10에서 임의의 기본으로 변환하는 bash 명령을 작성하려고 합니다(예를 들어 문자 az를 사용하여 기본 26으로 변환하지만 실제로는 사용 사례가 아닙니다).

가지다이 문제는 이전에 해결되었지만 bash에서는 해결되지 않았으며(내 경험이 제한되어 있음) 꽤 오랜 시간이 지나도 해결되지 않았습니다.

어떤 아이디어가 있나요?

답변1

비슷한 게 있어서 정리했어요

#!/bin/bash
#
# usage: convert_base <number-to-convert> <output-base> <output-digit-string>
#
# example:
#   $ convert_base 3735928559 16 "0 1 2 3 4 5 6 7 8 9 A B C D E F"
#   DEADBEEF

decimal_number=$1
output_base=$2
read -ra output_digits <<< "$3"

# TODO various assertions

if ((decimal_number == 0)); then
    output=${output_digits[0]}
else
    while ((decimal_number > 0)); do
        digit=$(( decimal_number % output_base ))
        output="${output_digits[digit]}$output"
        decimal_number=$(( decimal_number / output_base ))
    done
fi

printf '%s\n' "$output"

답변2

2-64를 십진수로 - 그냥 사용하세요내장 BASH$((기본#번호))

> echo $(( 36#B002RD3KCS ))
1117165531505356
> echo $(( 16#FF ))
255

복원 변환은 표준 bc + 도우미 기능을 사용하여 수행할 수 있습니다.

# base10 to base2..base52
# Usage: decimal_to_anybase <OtputBase> <DecimalNum>
function decimal_to_anybase()
{
   BASE52=($(echo {0..9} {A..Z} {a..z}));   # array of 'base_digits'
   base="$1";                               # output base 2..52
   arg="$2";                                # source decimal
   res=$(bc <<< "obase=$base; $arg")
   if [ "$base" -le 16 ]; then              # bases 2..16 returned as is 
       echo "$res"
   else                                     # bases 17..52 returned as array indexes
      for i in $res; do 
          echo -n ${BASE52[$(( 10#$i ))]}   # output BASE52[base_digit]
      done && echo
   fi 
}

> decimal_to_anybase 36 1117165531505356
B002RD3KCS

답변3

어쩌면 당연한 사실일지도 모르지만, bash에는 printf기본 8과 16을 수행할 수 있는 내장 함수가 있습니다.

$ printf '%o\n' 1234
2322
$ printf '%#o\n' 1234
02322
$ printf '%x\n' 1234
4d2
$ printf '%#x\n' 1234
0x4d2
$ printf '%X\n' 1234
4D2
$ printf '%#X\n' 1234
0X4D2

16진수 부동 소수점 숫자:

$ LC_ALL=C printf '%a\n' 1234.56
0x9.a51eb851eb851ecp+7
$ LC_ALL=C printf '%A\n' 1234.56
0X9.A51EB851EB851ECP+7

LC_ALL=C( 10진수 기수 문자가 임을 확인하기 위해 여기에서 사용됨 .)

그러나 더 고급 셸(예: zsh 또는 ksh93)이 필요한 다른 기반은 지원하지 않으며 수동으로 수행할 수 없습니다.

결과를 변수에 저장하려면 다음을 수행하십시오.

printf -v oct %o 1234

다음보다 더 효율적입니다:

oct=$(printf %o 1234)

bash에서(ksh93 또는 일부 BSD의 sh와 반대) 프로세스를 분기하고 결과를 파이프를 통해 보내는 것을 의미합니다.

Bash를 좋아하지 않는 사람들을 위해 다른 쉘에 대한 몇 가지 대안을 다음에서 찾을 수 있습니다.

관련 정보