답변:
다른 답변은 처음부터 고정 된 양의 문자를 숨기고 평문 접미어의 길이는 다양합니다. 대안은 고정 된 수의 문자를 일반 텍스트로 남겨두고 마스크 처리 된 부분의 길이를 변경하는 것입니다. 어느 것이 더 유용한 지 모르겠지만 다른 선택은 다음과 같습니다.
#!/bin/bash
mask() {
local n=3 # number of chars to leave
local a="${1:0:${#1}-n}" # take all but the last n chars
local b="${1:${#1}-n}" # take the final n chars
printf "%s%s\n" "${a//?/*}" "$b" # substitute a with asterisks
}
mask abcde
mask abcdefghijkl
이것은 인쇄 **cde
및 *********jkl
.
원하는 경우 n
짧은 문자열을 수정 하여 대부분의 문자열이 마스크되도록 할 수도 있습니다 . 예를 들어 이렇게하면 짧은 문자열 일지라도 최소한 3 개의 문자가 마스킹됩니다. (so- abcde
> ***de
및 abc
-> ***
) :
mask() {
local n=3
[[ ${#1} -le 5 ]] && n=$(( ${#1} - 3 ))
local a="${1:0:${#1}-n}"
local b="${1:${#1}-n}"
printf "%s%s\n" "${a//?/*}" "$b"
}
한 가지 옵션은 다음 echo
과 같은 대신 함수를 사용하도록하는 것입니다 .
obfuprint() {
if [ "${#1}" -ge 8 ]
then
printf '%s\n' "${1/????????/********}"
else
printf '%s\n' "${1//?/*}"
fi
}
그런 다음 전화를 걸고 obfuprint 'secretvalue'
받을 수 있습니다 ********lue
(후행 줄 바꿈). 이 함수는 매개 변수 확장을 사용하여 전달 된 값의 처음 8자를 검색하고 8 개의 별표로 대체합니다. 들어오는 값이 8 자보다 짧은 경우 모두 별표로 바뀝니다. 8 개 이상의 문자 입력에 대한 나의 초기 가정을 지적한 ilkkachu 에게 감사드립니다 !
에서 영감을 받다 ilkkachu의 유연한 masking answer 에서 문자열의 일부 비율을 무작위로 마스킹하는 변형을 추가하는 것이 흥미로울 것이라고 생각했습니다.
obfuprintperc () {
local perc=75 ## percent to obfuscate
local i=0
for((i=0; i < ${#1}; i++))
do
if [ $(( $RANDOM % 100 )) -lt "$perc" ]
then
printf '%s' '*'
else
printf '%s' "${1:i:1}"
fi
done
echo
}
이것은 bash의 $RANDOM
특수 변수 에 의존 합니다. 단순히 입력의 각 문자를 반복하여 해당 문자를 마스킹 할 것인지 인쇄 할 것인지 결정합니다. 샘플 출력 :
$ obfuprintperc 0123456789
0*****6*8*
$ obfuprintperc 0123456789
012***678*
$ obfuprintperc 0123456789
**********
$ obfuprintperc 0123456789
*****56***
$ obfuprintperc 0123456789
0*******8*
에 배관을 시도 할 수 sed
있습니다. 예를 들어 문자열의 처음 8자를 별표로 바꾸려면 다음과 같이 sed 's/^......../********/'
명령으로 파이프 할 수 있습니다 .
$ echo 'secretvalue' | sed 's/^......../********/'
********lue
이를 수행하는 함수를 정의 할 수도 있습니다.
obsecho () { echo "$1" | sed 's/^......../*********/'; }
sed 's/^......../********/' <<< 'secretvalue'
bash -c 'lsof -d0 -a -p $$ 2>/dev/null' <<< foo
.
zsh
변형이 마스크 텍스트의 사분의 삼 :
mask() printf '%s\n' ${(l:$#1::*:)1:$#1*3/4}
예:
$ mask secretvalue
********lue
$ mask 12345678
******78
$ mask 1234
***4
처음 8자를 숨기려면
mask() printf '%s\n' ${(l:$#1::*:)1:8}
마지막 3자를 제외한 모든 문자를 숨기려면
mask() printf '%s\n' ${(l:$#1::*:)1: -3}
임의의 수의 문자를 마스킹하려면
mask() printf '%s\n' ${(l:$#1::*:)1: RANDOM%$#1}
Bash의 또 다른 옵션은 간단하지 않다면 eval
몇 가지로 할 수 있습니다 printf
.
# example data
password=secretvalue
chars_to_show=3
# the real thing
eval "printf '*%.0s' {1..$((${#password} - chars_to_show))}"
printf '%s\n' "${password: -chars_to_show}"
그러나 조심하십시오.
${#password}
보다 적을 때 필요에 따라 위의 문제를 해결하십시오.${chars_to_show}
eval
신뢰할 수없는 입력 매우 위험 할 수 있습니다 : 여기에 입력 안전 소스에서만 제공 있기 때문에 안전한 것으로 간주 될 수있다, 즉의 길이 ${password}
와 값의${chars_to_show}
다음 은 정규식과 유사한 검색을 문자열 대체와 결합하는 방법을 보여주는 장난감 Bash 스크립트입니다.
strip_str.sh
#!/usr/bin/env bash
_str="${1}"
_filter="${2:-'apl'}"
echo "${_str//[${_filter}]/}"
strip_str.sh 'apple-foo bar'
# -> e-foo br
strip_str.sh 'apple-foo bar' 'a'
# -> pple-foo br
privatize_str.sh
#!/usr/bin/env bash
_str="${1}"
_filter="${2:-'apl'}"
_replace="${3:-'*'}"
echo "${_str//[${_filter}]/${_replace}}"
privatize_str.sh 'apple-foo bar'
# -> ****e-foo b*r
restricted_str.sh
#!/usr/bin/env bash
_str="${1}"
_valid="${2:-'a-z'}"
_replace="${3:-''}"
echo "${_str//[^${_valid}]/${_replace}}"
restricted_str.sh 'apple-foo bar'
# -> applefoobar
주요 테이크 아웃
[a-z 0-9]
Bash <search>
내에서 완전히 유효하고 편리합니다.${_var_name//<search>/<replace>}
^
이 문맥 내에서 정반대 not
검색과 반대로내가 얻을 수 있지만 그것은
printf
이다 더 나은 거의 모든 사용 사례에서 위의 코드를 사용echo
하므로 지나치게 무슨 일이 일어나고 있는지 혼동하지에있다.
obfuscate_str.sh
#!/usr/bin/env bash
_str="${1}"
_start="${2:-6}"
_header="$(for i in {1..${_start}}; do echo -n '*'; done)"
echo "${_header}${_str:${_start}}"
obfuscate_str.sh 'apple-foo bar' 3
# -> ***le-foo bar