5

所以我有这个功能,输出如下:

    AGsg4SKKs74s62#

我需要找到一种在不删除任何内容的情况下对字符进行加扰的方法。也就是说,在我加扰它们之后,所有字符都必须存在。

我只能 bash 实用程序,包括 awk 和 sed。

4

4 回答 4

9
echo 'AGsg4SKKs74s62#' | sed 's/./&\n/g' | shuf | tr -d "\n"

输出(例如):

S7s64#2gKAGsKs4
于 2014-10-12T14:43:59.180 回答
5

这是一个完成这项工作的纯 Bash 函数:

scramble() {
    # $1: string to scramble
    # return in variable scramble_ret
    local a=$1 i
    scramble_ret=
    while((${#a})); do
        ((i=RANDOM%${#a}))
        scramble_ret+=${a:i:1}
        a=${a::i}${a:i+1}
    done
}

看看它是否有效:

$ scramble 'AGsg4SKKs74s62#'
$ echo "$scramble_ret"
G4s6s#2As74SgKK

看起来没问题。

于 2014-10-12T15:49:03.183 回答
3

我知道您没有提到 Perl,但可以这样做:

perl -MList::Util=shuffle -F'' -lane 'print shuffle @F' <<<"AGsg4SKKs74s62#"

-a启用自动拆分模式并将-F''字段分隔符设置为空字符串,因此每个字符都进入一个单独的数组元素。使用核心模块提供的函数对数组进行洗牌List::Util

于 2014-10-12T14:55:22.573 回答
0

这是我的解决方案,用法:shuffleString "any-string"。使用 bash 时,我不考虑性能。

function shuffleString() {
    local line="$1"
    for i in $(seq 1 ${#line}); do
        local p=$(expr $RANDOM % ${#line})
        if [[ $p -lt $i ]]; then
            local line="${line:0:$p}${line:$i:1}${line:$p+1:$i-$p-1}${line:$p:1}${line:$i+1}"
        elif [[ $p -gt $i ]]; then
            local line="${line:0:$i}${line:$p:1}${line:$i+1:$p-$i-1}${line:$i:1}${line:$p+1}"
        fi
    done
    echo "$line"
}
于 2018-08-05T06:22:15.980 回答