Gizleme ile yankı


15

Ekrana bazı değişkenler yazdırmak gerekiyor ama ilk birkaç karakteri tercihli olarak şaşırtmak gerekiyor ve ben terminalde yazdırırken gizli bir değerin ilk karakterlerini şaşırtmak bash bir echo komutu olup olmadığını merak ediyordum:

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

Yanıtlar:


11

Diğer cevaplar, başlangıçtan itibaren sabit miktarda karakteri maskeliyor ve düz metin sonekinin uzunluğu değişiyor. Bir alternatif, düz metinde sabit miktarda karakter bırakmak ve maskelenen parçanın uzunluğunu değiştirmek olabilir. Hangisinin daha yararlı olduğunu bilmiyorum, ama işte diğer seçenek:

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

Bu yazdırır **cdeve *********jkl.


İsterseniz n, dizenin çoğunun maskelenmesini sağlamak için kısa dizeler için de değişiklik yapabilirsiniz. Örneğin bu, kısa dizeler için bile en az üç karakterin maskelenmesini sağlar. (yani abcde-> ***deve 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

Bir seçenek kendinizi aşağıdaki echogibi bir işlevi kullanmaya zorlamak olacaktır :

obfuprint() {
  if [ "${#1}" -ge 8 ]
  then
    printf '%s\n' "${1/????????/********}"
  else
    printf '%s\n' "${1//?/*}"
  fi
}

Sonra arayabilir obfuprint 'secretvalue've alabilirsiniz ********lue(sondaki bir yeni satır ile). İşlev, geçirilen değerin ilk sekiz karakterini aramak için parametre genişletmeyi kullanır ve bunları sekiz yıldız işareti ile değiştirir. Gelen değer sekiz karakterden daha kısaysa, bunların yerine yıldız işaretleri konur. İlkkachu sayesindeİlk sekiz veya daha fazla karakter girişi varsayımımdan için !


İlkkachu'nun esnek maskeleme cevabından esinlenerek, dizenin bir yüzdesini rastgele maskeleyen bir varyasyon eklemenin ilginç olacağını düşündüm:

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
}

Bu, bash'ın $RANDOMözel değişkenine dayanır ; yalnızca girişin her karakterini dolaşır ve o karakterin maskelenmesine veya yazdırılmasına karar verir. Örnek çıktı:

$ obfuprintperc 0123456789
0*****6*8*
$ obfuprintperc 0123456789
012***678*
$ obfuprintperc 0123456789
**********
$ obfuprintperc 0123456789
*****56***
$ obfuprintperc 0123456789
0*******8*

Açıkçası, rastgele maskelemeyi sevmiyorum. Kararlı bir omuz sörfçüsü sonunda benimle küçük bir konuşma yapmak gibi davranarak sırlarımı alacak.
emory

Kesinlikle, hassas bilgilerin gösterilmesi dikkatle yapılmalıdır! Sabit önek maskeleme ve değişken önek maskelemeye alternatif olarak rastgele maskeleme sundum.
Jeff Schaller

4
Ben de sabit önek veya değişken önek maskeleme hayranı değilim, ama bunlarla sır olarak gizli kalan bir "çekirdek" var. Rastgele maskelemede "çekirdek" yoktur. Sonunda her şey bu hastaya yeterince açıklanacak.
emory

7

Boru tesisatını deneyebilirsiniz sed. Örneğin, bir dizenin ilk 8 karakterini yıldız işaretleri ile değiştirmek için sed 's/^......../********/'komuta geçebilirsiniz , örneğin:

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

Bunu yapan bir işlev de tanımlayabilirsiniz:

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

2
Ben öneririm printfüzerindeecho gibi verilerin yorumlanması için size tabi olmadığınızı yüzden \rya\n
Jeff Schaller

@JeffSchaller SE'de yayınlamamın nedenlerinden biri de bu. İyi bir nokta. Geri dönüşünüz için teşekkür ederiz.
Igal

Birçok şeylerden biri ben oldum , hem de zaman zaman burada öğrenilen! Geçtiği için mutluyum!
Jeff Schaller

1
Bunun yerine bir ringa balığı kullanabileceğinizde bir boru kullanmaya gerek yok:sed 's/^......../********/' <<< 'secretvalue'
wjandrea

@roaima Aslında geçici bir dosya. Eğer görürseniz görebilirsiniz bash -c 'lsof -d0 -a -p $$ 2>/dev/null' <<< foo.
19L JoL

7

zshMetnin dörtte üçünü maskeleyen bir varyant:

mask() printf '%s\n' ${(l:$#1::*:)1:$#1*3/4}

Misal:

$ mask secretvalue
********lue
$ mask 12345678
******78
$ mask 1234
***4

İlk 8 karakteri maskelemek için:

mask() printf '%s\n' ${(l:$#1::*:)1:8}

Son 3 karakter hariç tümünü maskelemek için:

mask() printf '%s\n' ${(l:$#1::*:)1: -3}

Rastgele sayıda karakteri maskelemek için:

mask() printf '%s\n' ${(l:$#1::*:)1: RANDOM%$#1}

2

Bash'teki başka bir seçenek, basit bir şey sakıncası evalyoksa bunu bir çift ile yapabilirsiniz 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}"

Ama dikkat et:

  • ${#password}daha az olduğunda yukarıdakileri ihtiyacınız olan şekilde düzeltin${chars_to_show}
  • evalgüvenilmeyen girdi ile çok tehlikeli olabilir: burada güvenli kabul edilebilir, çünkü girdisi sadece güvenli kaynaklardan gelir, yani uzunluğu ${password}ve değeri${chars_to_show}

0

Regex benzeri aramanın dize ikamesi ile nasıl birleştirileceğini gösteren bazı oyuncak Bash komut dosyaları.

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

Temel çıkarımlar

  • [a-z 0-9]Bir şekilde, tamamen geçerli ve kullanışlı <search>olan${_var_name//<search>/<replace>}Bash için
  • ^, bu bağlamda, ters veya notnormal ifade benzeri aramalar içindir
  • Yerleşikler genellikle daha hızlıdır ve özellikle gereksiz boruları kestiğinde daha özlüdür

Elde iken o printfolduğunu daha iyi neredeyse tüm kullanım durumları yukarıdaki kod kullanır echoböylece aşırı neler karışıklık yaratmamak için.

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
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.