Echo với obfuscation


15

Tôi cần in một số biến lên màn hình nhưng tôi cần làm xáo trộn một vài ký tự đầu tiên và tôi tự hỏi liệu có một lệnh echo trong bash có thể làm xáo trộn các ký tự đầu tiên của một giá trị bí mật trong khi in nó tới thiết bị đầu cuối không:

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

Câu trả lời:


11

Các câu trả lời khác che giấu một số lượng ký tự cố định từ đầu, với hậu tố văn bản khác nhau về chiều dài. Một cách khác là để lại một lượng ký tự cố định trong văn bản gốc và thay đổi độ dài của phần bị che. Tôi không biết cái nào hữu ích hơn, nhưng đây là lựa chọn khác:

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

Điều này in **cde*********jkl.


Nếu bạn thích, bạn cũng có thể sửa đổi ncác chuỗi ngắn để đảm bảo phần lớn chuỗi được che. Ví dụ, điều này sẽ đảm bảo ít nhất ba ký tự được che dấu ngay cả đối với các chuỗi ngắn. (vì vậy 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"
}

13

Một lựa chọn sẽ là buộc bản thân sử dụng một chức năng thay vì echo, chẳng hạn như:

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

Sau đó, bạn có thể gọi obfuprint 'secretvalue'và nhận ********lue(với một dòng mới). Hàm sử dụng mở rộng tham số để tìm kiếm tám ký tự đầu tiên của giá trị được truyền vào và thay thế chúng bằng tám dấu sao. Nếu giá trị đến ngắn hơn tám ký tự, tất cả chúng đều được thay thế bằng dấu hoa thị. Cảm ơn ilkkachu đã chỉ ra giả định ban đầu của tôi về đầu vào tám ký tự trở lên!


Lấy cảm hứng từ câu trả lời mặt nạ linh hoạt của ilkkachu , tôi nghĩ thật thú vị khi thêm một biến thể che dấu ngẫu nhiên một số phần trăm của chuỗi:

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
}

Điều này phụ thuộc vào $RANDOMbiến đặc biệt của bash ; nó chỉ đơn giản là lặp qua từng ký tự của đầu vào và quyết định xem có che dấu ký tự đó hay in nó không. Đầu ra mẫu:

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

Thành thật mà nói, tôi không thích mặt nạ ngẫu nhiên. Một người lướt vai quyết đoán cuối cùng sẽ có được bí mật của tôi bằng cách giả vờ thích nói chuyện nhỏ với tôi.
emory

Chắc chắn, hiển thị thông tin nhạy cảm nên được thực hiện cẩn thận! Tôi đã trình bày mặt nạ ngẫu nhiên như là một thay thế cho mặt nạ tiền tố cố định và mặt nạ tiền tố biến.
Jeff Schaller

4
Tôi cũng không phải là một fan hâm mộ của mặt nạ tiền tố cố định hoặc tiền tố biến đổi, nhưng với những cái đó tồn tại một "hạt nhân" bí mật của tôi vẫn còn bí mật. Với mặt nạ ngẫu nhiên, không có "kernel". Cuối cùng, mọi thứ sẽ được tiết lộ cho những bệnh nhân đó.
emory

7

Bạn có thể thử đường ống đến sed. Ví dụ: để thay thế 8 ký tự đầu tiên của chuỗi bằng dấu hoa thị, bạn có thể chuyển sang sed 's/^......../********/'lệnh, ví dụ:

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

Bạn cũng có thể định nghĩa một hàm thực hiện điều này:

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

2
Tôi muốn đề nghị printftrênecho để bạn không phải chịu giải thích dữ liệu như \rhoặc\n
Jeff Schaller

@JeffSchaller Đây là một trong những lý do tại sao tôi đăng bài trên SE. Điểm tốt. Cảm ơn vì bạn đã phản hồi.
Igal

Đó cũng là một trong nhiều điều tôi học được ở đây! Hạnh phúc khi vượt qua nó cùng!
Jeff Schaller

1
Không cần sử dụng đường ống khi bạn có thể sử dụng một di truyền thay thế:sed 's/^......../********/' <<< 'secretvalue'
wjandrea

@roaima Đây thực sự là một tập tin thông thường tạm thời. Bạn có thể nhìn thấy nó nếu bạn làm bash -c 'lsof -d0 -a -p $$ 2>/dev/null' <<< foo.
JoL

7

Một zshbiến thể che dấu ba phần tư của văn bản:

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

Thí dụ:

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

Để che dấu 8 ký tự đầu tiên:

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

Để che dấu tất cả trừ 3 ký tự cuối cùng:

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

Để che dấu một số ký tự ngẫu nhiên:

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

2

Một tùy chọn khác trong Bash, nếu bạn không phiền một cách đơn giản, evalbạn có thể thực hiện với một vài điều printfsau:

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

Nhưng hãy cẩn thận:

  • khắc phục những điều trên khi bạn cần khi ${#password}ít hơn${chars_to_show}
  • evalcó thể rất nguy hiểm với đầu vào không đáng tin cậy: ở đây có thể được coi là an toàn vì đầu vào của nó chỉ đến từ các nguồn an toàn, tức là độ dài ${password}và giá trị của${chars_to_show}

0

Đây là một số kịch bản Bash đồ chơi để chơi với nó cho thấy cách kết hợp tìm kiếm giống như biểu thức chính quy với thay thế chuỗi.

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

Chìa khóa chính

  • [a-z 0-9]là hoàn toàn hợp lệ và tiện dụng, như một phần <search>trong ${_var_name//<search>/<replace>}Bash
  • ^, trong bối cảnh này, là đảo ngược hoặc notcho các tìm kiếm giống như regex
  • Tích hợp thường nhanh hơn và thường ngắn gọn hơn, đặc biệt là khi nó cắt các đường ống không cần thiết

Trong khi tôi nhận được rằng printftốt hơn trong hầu hết các trường hợp sử dụng những ứng dụng mã trên echođể không quá nhầm lẫn giữa những gì đang xảy ra.

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.