我需要在屏幕上打印一些变量,但我需要优先混淆前几个字符,我想知道 bash 中是否有一个 echo 命令可以混淆秘密值的第一个字符,同时将其打印到终端:
echo 'secretvalue'
********lue
Run Code Online (Sandbox Code Playgroud)
Jef*_*ler 14
一种选择是强迫自己使用函数而不是echo
,例如:
obfuprint() {
if [ "${#1}" -ge 8 ]
then
printf '%s\n' "${1/????????/********}"
else
printf '%s\n' "${1//?/*}"
fi
}
Run Code Online (Sandbox Code Playgroud)
然后你可以调用obfuprint 'secretvalue'
和接收********lue
(带有尾随换行符)。该函数使用参数扩展来搜索传入值的前八个字符,并用八个星号替换它们。如果传入的值短于八个字符,则它们都将替换为星号。感谢ilkkachu指出我最初假设输入的字符数为 8 个或更多!
受到ilkkachu 的灵活屏蔽答案的启发,我认为添加一个随机屏蔽部分字符串的变体会很有趣:
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
}
Run Code Online (Sandbox Code Playgroud)
这依赖于 bash 的$RANDOM
特殊变量;它只是遍历输入的每个字符并决定是屏蔽该字符还是打印它。示例输出:
$ obfuprintperc 0123456789
0*****6*8*
$ obfuprintperc 0123456789
012***678*
$ obfuprintperc 0123456789
**********
$ obfuprintperc 0123456789
*****56***
$ obfuprintperc 0123456789
0*******8*
Run Code Online (Sandbox Code Playgroud)
ilk*_*chu 13
其他答案从一开始就屏蔽了固定数量的字符,纯文本后缀的长度各不相同。另一种方法是在明文中保留固定数量的字符,并改变掩码部分的长度。我不知道哪个更有用,但这是另一种选择:
#!/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
Run Code Online (Sandbox Code Playgroud)
这会打印**cde
和*********jkl
。
如果您愿意,您还可以修改n
短字符串以确保大部分字符串被屏蔽。例如,这将确保即使对于短字符串也至少屏蔽三个字符。(所以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"
}
Run Code Online (Sandbox Code Playgroud)
你可以尝试管道到sed
. 例如,要用星号替换字符串的前 8 个字符,您可以通过管道连接到sed 's/^......../********/'
命令,例如:
$ echo 'secretvalue' | sed 's/^......../********/'
********lue
Run Code Online (Sandbox Code Playgroud)
您还可以定义一个执行此操作的函数:
obsecho () { echo "$1" | sed 's/^......../*********/'; }
Run Code Online (Sandbox Code Playgroud)
一个zsh
变种,掩盖了文字的四分之三:
mask() printf '%s\n' ${(l:$#1::*:)1:$#1*3/4}
Run Code Online (Sandbox Code Playgroud)
例子:
$ mask secretvalue
********lue
$ mask 12345678
******78
$ mask 1234
***4
Run Code Online (Sandbox Code Playgroud)
屏蔽前 8 个字符:
mask() printf '%s\n' ${(l:$#1::*:)1:8}
Run Code Online (Sandbox Code Playgroud)
要屏蔽除最后 3 个字符以外的所有字符:
mask() printf '%s\n' ${(l:$#1::*:)1: -3}
Run Code Online (Sandbox Code Playgroud)
要屏蔽随机数量的字符:
mask() printf '%s\n' ${(l:$#1::*:)1: RANDOM%$#1}
Run Code Online (Sandbox Code Playgroud)