Gema dengan kebingungan

15

Saya perlu mencetak beberapa variabel ke layar tetapi saya harus mengaburkan beberapa karakter pertama dan saya bertanya-tanya apakah ada perintah gema dalam bash yang dapat mengaburkan karakter pertama dari nilai rahasia saat mencetaknya ke terminal:

echo 'secretvalue'
********lue
Xerxes
sumber

Jawaban:

11

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 **cdedan *********jkl.


Jika suka, Anda juga bisa memodifikasi nstring 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"
}
ilkkachu
sumber
13

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 $RANDOMvariabel 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*
Jeff Schaller
sumber
Terus terang, saya tidak suka topeng acak. Peselancar yang tekun pada akhirnya akan mendapatkan rahasia saya dengan berpura-pura suka berbasa-basi dengan saya.
emory
Tentu saja, menampilkan informasi sensitif harus dilakukan dengan hati-hati! Saya menyajikan masking acak sebagai alternatif untuk masking fixed-prefix dan masking variabel-awalan.
Jeff Schaller
4
Saya juga bukan penggemar tetap-awalan atau variabel-awalan, tetapi dengan mereka ada "kernel" dari rahasia saya yang tetap rahasia. Dengan masking acak, tidak ada "kernel". Akhirnya semuanya akan diungkapkan kepada pasien itu cukup.
emory
7

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/^......../*********/'; }
igal
sumber
2
Saya sarankan printflebihecho sehingga Anda tidak dikenakan menafsirkan data seperti \ratau\n
Jeff Schaller
@JeffSchaller Ini adalah salah satu alasan mengapa saya memposting di SE. Poin yang bagus. Terima kasih untuk umpan baliknya.
igal
Itu salah satu dari banyak hal yang saya pelajari di waktu saya di sini, juga! Senang menyebarkannya!
Jeff Schaller
1
Tidak perlu menggunakan pipa saat Anda dapat menggunakan herestring sebagai gantinya:sed 's/^......../********/' <<< 'secretvalue'
wjandrea
@roaima Ini sebenarnya file biasa sementara. Anda dapat melihatnya jika Anda melihatnya bash -c 'lsof -d0 -a -p $$ 2>/dev/null' <<< foo.
JoL
7

Sebuah zshvarian 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}
Stéphane Chazelas
sumber
2

Opsi lain di Bash, jika Anda tidak keberatan satu hal sederhana, evalAnda 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:

  • perbaiki yang di atas seperti yang Anda butuhkan saat ${#password}kurang dari${chars_to_show}
  • evalbisa 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}
LL3
sumber
0

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 notuntuk pencarian seperti-regex
  • Built-in umumnya lebih cepat dan sering lebih ringkas, terutama ketika memotong pipa yang tidak dibutuhkan

Sementara saya mendapatkan bahwa printfadalah lebih baik dalam hampir semua kasus penggunaan di atas menggunakan kode echosehingga 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
S0AndS0
sumber