สะท้อนด้วยความงงงวย


15

ฉันต้องการพิมพ์ตัวแปรบางอย่างไปที่หน้าจอ แต่ฉันต้องทำให้ยุ่งเหยิงกับตัวละครสองสามตัวแรกก่อนและฉันสงสัยว่ามีคำสั่ง echo ในการทุบตีที่สามารถทำให้ตัวอักษรตัวแรกของค่าลับในขณะพิมพ์ไปยังเทอร์มินัล:

echo 'secretvalue'
********lue

คำตอบ:


11

คำตอบอื่น ๆ จะปกปิดจำนวนอักขระตั้งแต่เริ่มต้นด้วยส่วนต่อท้ายแบบธรรมดาที่มีความยาวต่างกัน อีกทางเลือกหนึ่งคือปล่อยให้จำนวนอักขระคงที่ในข้อความธรรมดาและเพื่อเปลี่ยนความยาวของส่วนที่ถูกสวมหน้ากาก ฉันไม่ทราบว่าตัวเลือกใดมีประโยชน์มากกว่า แต่นี่คือตัวเลือกอื่น:

#!/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"
}

13

ทางเลือกหนึ่งคือบังคับให้คุณใช้ฟังก์ชั่นแทน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*

เพื่อความตรงไปตรงมาฉันไม่ชอบการหลอกลวงแบบสุ่ม นักท่องไหล่ที่มุ่งมั่นในที่สุดจะได้รับความลับของฉันโดยแกล้งทำเป็นชอบพูดคุยเล็ก ๆ กับฉัน
emory

แน่นอนว่าควรแสดงข้อมูลที่ละเอียดอ่อนอย่างระมัดระวัง! ฉันนำเสนอการพรางแบบสุ่มเป็นอีกทางเลือกหนึ่งในการกำบังแบบคงที่และคำนำหน้าตัวแปร
Jeff Schaller

4
ฉันไม่ได้เป็นแฟนของคำนำหน้าคงที่หรือคำนำหน้าตัวแปร - อย่างใดอย่างหนึ่ง แต่ด้วยสิ่งเหล่านั้นมี "เคอร์เนล" ของความลับของฉันที่ยังคงเป็นความลับ ด้วยการปิดบังแบบสุ่มไม่มี "เคอร์เนล" ในที่สุดทุกอย่างจะถูกเปิดเผยต่อผู้ป่วยเหล่านั้นมากพอ
emory

7

sedคุณอาจจะลองท่อไป ตัวอย่างเช่นในการแทนที่อักขระ 8 ตัวแรกของสตริงด้วยเครื่องหมายดอกจันคุณสามารถไพพ์ไปยังsed 's/^......../********/'คำสั่งเช่น:

$ echo 'secretvalue' | sed 's/^......../********/'
********lue

คุณยังสามารถกำหนดฟังก์ชั่นที่ทำสิ่งนี้:

obsecho () { echo "$1" | sed 's/^......../*********/'; }

2
ผมขอแนะนำให้printfมากกว่าechoเพื่อให้คุณไม่ต้องแปลความหมายของข้อมูลเช่น\rหรือ\n
เจฟฟ์ Schaller

@JeffSchaller นี่คือหนึ่งในเหตุผลที่ฉันโพสต์ใน SE จุดดี. ขอบคุณสำหรับความคิดเห็น.
igal

มันเป็นหนึ่งในหลาย ๆ สิ่งที่ฉันได้เรียนรู้ในเวลาของฉันที่นี่เช่นกัน! ยินดีที่จะผ่านมันไป!
Jeff Schaller

1
ไม่จำเป็นต้องใช้ไพพ์เมื่อคุณสามารถใช้ herestring แทน:sed 's/^......../********/' <<< 'secretvalue'
wjandrea

@roaima จริงๆแล้วมันเป็นไฟล์ปกติชั่วคราว bash -c 'lsof -d0 -a -p $$ 2>/dev/null' <<< fooคุณสามารถดูได้ถ้าคุณทำ
JoL

7

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}

2

ตัวเลือกในการทุบตีอื่นถ้าคุณไม่คิดง่ายๆ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}

0

ต่อไปนี้เป็นสคริปต์ของเล่นทุบตีบางส่วนที่จะเล่นด้วยซึ่งแสดงวิธีรวมการค้นหาคล้าย 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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.