ฉันต้องการพิมพ์ตัวแปรบางอย่างไปที่หน้าจอ แต่ฉันต้องทำให้ยุ่งเหยิงกับตัวละครสองสามตัวแรกก่อนและฉันสงสัยว่ามีคำสั่ง echo ในการทุบตีที่สามารถทำให้ตัวอักษรตัวแรกของค่าลับในขณะพิมพ์ไปยังเทอร์มินัล:
echo 'secretvalue'
********lue
ฉันต้องการพิมพ์ตัวแปรบางอย่างไปที่หน้าจอ แต่ฉันต้องทำให้ยุ่งเหยิงกับตัวละครสองสามตัวแรกก่อนและฉันสงสัยว่ามีคำสั่ง echo ในการทุบตีที่สามารถทำให้ตัวอักษรตัวแรกของค่าลับในขณะพิมพ์ไปยังเทอร์มินัล:
echo 'secretvalue'
********lue
คำตอบ:
คำตอบอื่น ๆ จะปกปิดจำนวนอักขระตั้งแต่เริ่มต้นด้วยส่วนต่อท้ายแบบธรรมดาที่มีความยาวต่างกัน อีกทางเลือกหนึ่งคือปล่อยให้จำนวนอักขระคงที่ในข้อความธรรมดาและเพื่อเปลี่ยนความยาวของส่วนที่ถูกสวมหน้ากาก ฉันไม่ทราบว่าตัวเลือกใดมีประโยชน์มากกว่า แต่นี่คือตัวเลือกอื่น:
#!/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
สตริงสั้น ๆ เพื่อให้แน่ใจว่าส่วนใหญ่ของสตริงถูกปิดบัง เช่นนี้จะทำให้แน่ใจว่ามีตัวละครอย่างน้อยสามตัวถูกปิดบังแม้กับสายอักขระสั้น ๆ (ดังนั้น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
(พร้อมขึ้นบรรทัดใหม่) ฟังก์ชันใช้การขยายพารามิเตอร์เพื่อค้นหาอักขระแปดตัวแรกของค่าที่ส่งผ่านและแทนที่ด้วยเครื่องหมายดอกจันแปดตัว หากค่าที่เข้ามาสั้นกว่าแปดตัวอักษรพวกเขาทั้งหมดจะถูกแทนที่ด้วยเครื่องหมายดอกจัน ขอบคุณilkkachu ที่ชี้ให้เห็นข้อสันนิษฐานเบื้องต้นของฉันเกี่ยวกับอินพุตอักขระแปดตัวขึ้นไป!
แรงบันดาลใจจากคำตอบกำบังแบบยืดหยุ่นของ 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
}
สิ่งนี้อาศัย$RANDOM
ตัวแปรพิเศษของ bash มันวนซ้ำอักขระแต่ละตัวของอินพุตและตัดสินใจว่าจะปิดบังอักขระนั้นหรือพิมพ์ ตัวอย่างผลลัพธ์:
$ 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}
ตัวเลือกในการทุบตีอื่นถ้าคุณไม่คิดง่ายๆ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}
ต่อไปนี้เป็นสคริปต์ของเล่นทุบตีบางส่วนที่จะเล่นด้วยซึ่งแสดงวิธีรวมการค้นหาคล้าย regex กับการแทนที่สตริง
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]
ถูกต้องทั้งหมดและมีประโยชน์เป็น<search>
ภายใน${_var_name//<search>/<replace>}
สำหรับทุบตี^
ภายในบริบทนี้เป็นการค้นหาแบบย้อนกลับหรือnot
สำหรับการค้นหาแบบ regexในขณะที่ฉันได้รับที่
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