エマリと混乱

エマリと混乱

一部の変数を画面に印刷する必要がありますが、最初の数文字を難読化するのが最善です。端末に印刷するときに秘密の値の最初の文字を難読化できるbashのechoコマンドがあるかどうか疑問に思います。

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

答え1

1つのオプションは、強制的に関数を代わりに使用することですecho。たとえば、次のようになります。

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

obfuprint 'secretvalue'その後、電話をかけたり受けたりすることができます********lue(末尾の改行を含む)。この関数は引数拡張を使用して渡された値の最初の8文字を検索し、それを8つのアスタリスクに置き換えます。受信値が8文字未満の場合は、すべてアスタリスクに置き換えられます。ありがとうイルカチョ8文字以上の文字入力の初期仮定をご指摘いただきありがとうございます!


からインスピレーションを受ける柔軟なブロックに対する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*

答え2

他の答えは、長さの異なるプレーンテキストサフィックスを使用して、最初から固定数の文字をマスクします。別のアプローチは、プレーンテキストに固定数の文字を保持し、マスクされた部分の長さを変更することです。どちらが役に立つかはわかりませんが、ここに別のオプションがあります。

#!/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短い文字列を変更して、ほとんどの文字列がマスクされるようにすることもできます。たとえば、これは短い文字列であっても少なくとも3文字をマスクします。 (したがってabcde->***deabc-> ***):

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"
}

答え3

zshテキストの4分の3を覆うバリエーション:

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}

答え4

Bashのもう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}

関連情報