Jawaban:
Jawaban lainnya menutupi sejumlah karakter sejak awal, dengan akhiran plaintext bervariasi panjangnya. Alternatifnya adalah meninggalkan jumlah karakter tetap dalam plaintext, dan memvariasikan panjang bagian yang bertopeng. Saya tidak tahu yang mana yang lebih berguna, tapi ini pilihan lain:
#!/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
Ini mencetak **cde
dan *********jkl
.
Jika suka, Anda juga bisa memodifikasi n
string pendek untuk memastikan sebagian besar string tersamarkan. Misalnya ini akan memastikan setidaknya tiga karakter disembunyikan bahkan untuk string pendek. (jadi abcde
-> ***de
, dan 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"
}
Salah satu opsi adalah memaksa diri Anda untuk menggunakan fungsi alih-alih echo
, seperti:
obfuprint() {
if [ "${#1}" -ge 8 ]
then
printf '%s\n' "${1/????????/********}"
else
printf '%s\n' "${1//?/*}"
fi
}
Kemudian Anda dapat menelepon obfuprint 'secretvalue'
dan menerima ********lue
(dengan baris baru). Fungsi ini menggunakan ekspansi parameter untuk mencari delapan karakter pertama dari nilai yang diteruskan dan menggantinya dengan delapan tanda bintang. Jika nilai yang masuk lebih pendek dari delapan karakter, mereka semua diganti dengan tanda bintang. Terima kasih kepada ilkkachu karena menunjukkan asumsi awal saya tentang delapan atau lebih input karakter!
Terinspirasi oleh jawaban masking fleksibel ilkkachu , saya pikir akan menarik untuk menambahkan variasi yang secara acak menutupi beberapa persentase dari string:
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
}
Ini bergantung pada $RANDOM
variabel khusus bash ; itu hanya loop melalui setiap karakter input dan memutuskan apakah akan menutupi karakter itu atau mencetaknya. Output sampel:
$ obfuprintperc 0123456789
0*****6*8*
$ obfuprintperc 0123456789
012***678*
$ obfuprintperc 0123456789
**********
$ obfuprintperc 0123456789
*****56***
$ obfuprintperc 0123456789
0*******8*
Anda dapat mencoba perpipaan ke sed
. Misalnya, untuk mengganti 8 karakter pertama dari string dengan tanda bintang, Anda dapat menyalurkan kesed 's/^......../********/'
perintah, misalnya:
$ echo 'secretvalue' | sed 's/^......../********/'
********lue
Anda juga dapat mendefinisikan fungsi yang melakukan ini:
obsecho () { echo "$1" | sed 's/^......../*********/'; }
sed 's/^......../********/' <<< 'secretvalue'
bash -c 'lsof -d0 -a -p $$ 2>/dev/null' <<< foo
.
Sebuah zsh
varian yang masker tiga perempat dari teks:
mask() printf '%s\n' ${(l:$#1::*:)1:$#1*3/4}
Contoh:
$ mask secretvalue
********lue
$ mask 12345678
******78
$ mask 1234
***4
Untuk menutupi 8 karakter pertama:
mask() printf '%s\n' ${(l:$#1::*:)1:8}
Untuk menutupi semua kecuali 3 karakter terakhir:
mask() printf '%s\n' ${(l:$#1::*:)1: -3}
Untuk menutupi sejumlah karakter acak:
mask() printf '%s\n' ${(l:$#1::*:)1: RANDOM%$#1}
Opsi lain di Bash, jika Anda tidak keberatan satu hal sederhana, eval
Anda bisa melakukannya dengan beberapa 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}"
Tetapi berhati-hatilah:
${#password}
kurang dari${chars_to_show}
eval
bisa sangat berbahaya dengan input yang tidak dipercaya: di sini dapat dianggap aman karena inputnya hanya berasal dari sumber yang aman, yaitu panjang ${password}
dan nilai dari${chars_to_show}
Berikut ini beberapa skrip Bash mainan untuk dimainkan yang menunjukkan cara menggabungkan pencarian mirip-regex dengan penggantian string.
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
Takeaways kunci
[a-z 0-9]
benar-benar valid, dan praktis, sebagai bagian <search>
dalam ${_var_name//<search>/<replace>}
untuk Bash^
, dalam konteks ini, adalah kebalikan atau not
untuk pencarian seperti-regexSementara saya mendapatkan bahwa
printf
adalah lebih baik dalam hampir semua kasus penggunaan di atas menggunakan kodeecho
sehingga tidak terlalu bingung apa yang terjadi.
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