如何缩小 Ruby 源文件?

问题描述 投票:0回答:2

我有一种情况,我希望能够缩小(而不是编译)Ruby 脚本。目标是:

  1. 减少剧本整体字符数;
  2. 执行一定程度的混淆,使其他人难以修改代码。

我们可以假设:

  1. 是的,我知道我在做什么,而且我确实想缩小和混淆代码。
  2. Ruby 源代码语法简单,不使用任何高级元编程技术等。

是否有任何现有的库或工具?如果没有,开始开发简单的压缩器(理想情况下也用 Ruby 编写)的最佳方法是什么?

ruby minify
2个回答
3
投票

我创建了一个简单的脚本,它读取 Ruby 文件,生成缩小和混淆的版本,然后解释输出以再次重新生成它。我创建了一个 Ruby 文件并使用命令扩展来运行可以使用

ruby main.rb
:

执行的 Shell 脚本

主.rb

class MinifyAndObfuscateRuby
    def initialize(shell_script="./main.sh")
    @shell_script = shell_script
    run_shell_script
  end

  private

  def run_shell_script
    %x[sh #{@shell_script}]
  end
end

我编写了 Shell 脚本,它接受输入 Ruby 源文件并根据输入生成输出文件。或者,您可以直接使用

sh main.sh
运行它(而不是使用我为使用 RSpec 进行测试而添加的
main.rb
包装器)。请注意,存储库中共享的大部分 main.sh 代码如下所示,但为了简洁起见,我省略了
recover_source
函数的详细信息,该函数尝试在第二个输出文件中重新生成原始 Ruby 源文件。

main.sh

#!/bin/bash

# Purpose: Simple script that reads a Ruby file, generates a minified and 
# obfuscated version, and then interprets the output to regenerate it again. 
# Execute either by running `main.rb` Ruby file (uses command expansion to run this Shell script)
# with `ruby main.rb` or with directly with `sh main.sh`. Outputs are automatically
# generated in an ./outputs subdirectory.

# declare and instantiate variables
MINLEN=0 # optionally exclude iteration of blank lines when MINLENGTH is 1
input_file="./source.rb"
reverse=""
output_file="./outputs/output_minified_and_obfuscated.min.rb"
output_file_recovered="./outputs/output_unminified_and_unobfuscated.rb"

# obfuscate: by reversing each line
function obfuscate {
    for (( i=$len-1; i>=0; i-- )); do
        reverse="$reverse${line:$i:1}"
    done
    reverse+="\n"
}

# minify: find instances of the tuple keys in the variable containing the
# reversed input file string and replace with respective tuple values
function minify {
    find_data='eriuqer;*r* fed;*d* dne;*e* edulcni;*i* ssalc;*c* redaer_rtta;*ar*'; 
    for tuple in $find_data; do
        key=$(echo $tuple | cut -d ';' -f 1); 
        value=$(echo $tuple | cut -d ';' -f 2); 
        reverse=${reverse/$key/$value} 
    done
}

function process_source {
    # read lines from input file
    while IFS= read -r line || [ -n "$line" ]; do
        len=${#line}
        if [ "$len" -ge "$MINLEN" ]; then
            obfuscate
            minify
        fi
    done < "$input_file"

  echo "$output_file not found. Creating $output_file and adding minified and obfuscated contents"
  ! [[ -d "outputs" ]] && mkdir outputs
  touch $output_file
  echo $reverse >> $output_file
}

# check if output Ruby file already exists and if so regenerate source, otherwise create it
if [ -f "$output_file" ] && ! [ -f "$output_file_recovered" ]; then
  echo "$output_file already exists."
  recover_source # see source code for details of this method
  exit 0
elif [ -f "$input_file" ] && ! [ -f "$output_file_recovered" ]; then
    process_source
    exit 0
else
    echo "$output_file and $output_file_recovered have both already been generated."
    echo "Deleted temporary files and restarting process..."
    [ -f "$output_file" ] && rm -f "$output_file"
    [ -f "$output_file_recovered" ] && rm -f "$output_file_recovered"
    [ -d "outputs" ] && rmdir outputs
    exit 0
fi

我使用的示例源代码文件如下所示:

来源.rb

require 'bigdecimal'

class Obfiscate
    include Comparable

  attr_reader :name

  def initialize(name)
    @name = name
  end
end

它通过反转源文件中的每一行来应用一定程度的混淆,并使用正则表达式将 Ruby 语法替换为我自己的自定义缩写(即将

require
替换为
*r*
,将
class
替换为
*c*
,将
attr_accessor
替换为
*ar*
def
*d*
以及
end
*e*
),以减少总体字符数并可选择删除空白行,如下面的示例输出所示:

./outputs/output_minified_and_obfuscated.min.rb

'lamicedgib' *r*
etacsifbO *c*
elbarapmoC 
eman: *ar*
)eman(ezilaitini *d* 
eman = eman@ 
*e* 
*e*

0
投票

我最近开发了一个用于缩小 Ruby 代码的 gem: https://github.com/koic/minifyrb

在极端情况下,仍然存在一些导致缩小代码中不兼容行为的错误,但我认为它对于简单代码来说效果很好。我希望这些信息对遇到此问题的人有所帮助。

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.