BASH에서 정수를 단축된 영숫자 문자열로 변환하는 방법이 있습니까?
시작하면 var=20171019194210
. 나는 다음과 같은 것을 얻고 싶습니다.
echo "$var" | encoding
a4f5e6g
그런 다음:
echo "$var" | decoding
20171019194210
내가 뭔가를 찾았어Stackoverflow의 Python;그러나 가능하다면 GNU 도구를 조합하여 BASH를 사용하는 것을 선호합니다 awk
.
아래와 같이 타임스탬프를 생성하여 파일의 고유 ID를 생성하려고 합니다.
date +"%Y%m%d%H%M%S"
그런 다음 파일 이름에 이 타임스탬프를 포함시켜 전체 파일 이름이나 파일 이름의 나머지 부분을 사용하지 않고 시스템의 파일을 식별합니다.
이제 이 정수를 길이 측면에서 더 유용하게 만들기 위해 단축하거나 인코딩하고 싶지만 동일한 방식으로 타임스탬프 값을 다시 계산할 수 있습니다.
답변1
이것은 bash에 있으므로 느릴 것입니다. 2개의 숫자를 1개의 문자로 매핑합니다. base64 알파벳을 사용하므로 0에서 63 사이의 숫자만 수용할 수 있습니다. 시, 분, 초, 일, 월은 모두 작동하지만 2064년에는 작동이 중지됩니다. map
더 많은 문자로 확장하세요.
declare -a map=(
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
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
0 1 2 3 4 5 6 7 8 9 + /
)
declare -A revmap
for ((i=0; i<${#map[@]}; i++)); do revmap[${map[i]}]=$(printf "%02d" $i); done
encode() {
local i result=""
for ((i=0; $i < ${#1}; i+=2)); do
# specifies base 10 numbers to prevent attempted interpretation
# of invalid octal numbers 08,09
result+=${map[10#${1:i:2}]:-"?"}
done
echo "$result"
}
decode() {
local i result=""
for ((i=0; i<${#1}; i++)); do
result+=${revmap[${1:i:1}]:-"??"}
done
echo "$result"
}
encode 20171019194210 # => URKTTqK
decode $(encode 20171019194210) # => 20171019194210
encode 20671019194210 # => U?KTTqK
# .......^^
decode "$(encode 20671019194210)" # => 20??1019194210
답변2
얼마나 더 짧아질 것으로 예상하시나요? 16진수 표현을 사용하면 주어진 숫자 2자가 더 짧아집니다. 숫자가 길면 절약 효과가 더 커질 수 있습니다.
LONGER=20171019194210 #compare:
SHORTER=$(printf "%X\n" $LONGER) #12586E6F0F62
RESTORED=$(echo "obase=10; ibase=16; $SHORTER" | bc) #20171019194210