難読化によるエコー


15

私はいくつかの変数を画面に出力する必要がありますが、最初の数文字を難読化する必要があり、端末に印刷するときに秘密値の最初の文字を難読化できるエコーコマンドがbashにあるかどうか疑問に思っていました:

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、短い文字列を変更して、文字列の大部分がマスクされるようにすることもできます。たとえば、これにより、短い文字列でも少なくとも3文字がマスクされます。(つまり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

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に感謝します!


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
}

これは、bashの$RANDOM特殊変数に依存しています。入力の各文字をループし、その文字をマスクするか印刷するかを決定するだけです。サンプル出力:

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

率直に言って、ランダムマスキングは好きではありません。決意を固めた肩のサーファーは、私とちょっとした会話をするのを好むふりをして、最終的に私の秘密を取得します。
エモリー

確かに、機密情報の表示は慎重に行う必要があります!固定プレフィックスマスキングと可変プレフィックスマスキングの代替として、ランダムマスキングを紹介しました。
ジェフシャラー

4
私も固定プレフィックスまたは可変プレフィックスマスキングのファンではありませんが、それらには秘密のままの私の秘密の「カーネル」が存在します。ランダムマスキングでは、「カーネル」はありません。最終的にはすべてが十分にそれらの患者に明らかにされます。
エモリー

7

へのパイピングを試すことができsedます。たとえば、文字列の最初の8文字をアスタリスクに置き換えるにはsed 's/^......../********/'、たとえば次のようにコマンドにパイプできます。

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

これを行う関数を定義することもできます。

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

2
私がお勧めしたいprintf以上echoのようなデータ解釈にあなたが対象じゃないように\r\n
ジェフ・シャラー

@JeffSchallerこれが、私がSEに投稿する理由の1つです。いい視点ね。フィードバックをお寄せいただきありがとうございます。
イガル

それは多くのものの一つだ私がきたとしても、ここで私の時間に学びました!それを渡すことを嬉しく思います!
ジェフシャラー

1
:あなたの代わりにherestringを使用することができたときにパイプを使用する必要はありませんsed 's/^......../********/' <<< 'secretvalue'
wjandrea

@roaima実際には一時的な通常ファイルです。そうすればそれを見ることができますbash -c 'lsof -d0 -a -p $$ 2>/dev/null' <<< foo
JoL

7

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}

2

Bashのもう1つのオプションは、単純なものevalを気にしない場合は、次の2つの方法で実行できます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

正規表現のような検索と文字列の置換を組み合わせる方法を示すいくつかのおもちゃの Bashスクリプトがあります。

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]Bashの<search>内部として完全に有効で便利です${_var_name//<search>/<replace>}
  • ^このコンテキスト内では、逆またはnot正規表現のような検索用です
  • ビルトインは一般に高速であり、特に不要な配管を切り取る場合は特に簡潔です。

起こっていることを過度に混乱させないために、上記のコードが使用するほとんどすべてのユースケースでそれ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.