2016-10-19 20 views
-1

我有一種情況,我希望能夠minify(不編譯)Ruby腳本。目標是:如何縮小Ruby源文件?

  1. 減少腳本的總體字符數;
  2. 執行一定程度的模糊處理,使其他人難以修改代碼。

我們可以假設:

  1. 是的,我知道我在做什麼,我真的要壓縮和模糊處理的代碼。
  2. 源代碼Ruby代碼具有簡單的語法,不使用任何高級元編程技術等。

是否有任何現有的庫或工具呢?如果不是,開始開發一個簡單的縮小器(理想情況下,也用Ruby編寫)最好的方法是什麼?

回答

0

我創建了一個simple script that reads a Ruby file, generates a minified and obfuscated version, and then interprets the output to regenerate it again。我創建一個Ruby文件和使用的命令膨脹運行可與ruby main.rb執行的殼牌腳本:

main.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 

我寫的外殼腳本,它接受一個輸入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 

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

source.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 = [email protected] 
*e* 
*e* 
+1

嗨盧克,感謝您的非常詳細的答案和努力水平!不幸的是,在我縮小了一些仍然可執行的Ruby代碼之後 - 如果在問題中沒有明確表示抱歉。類似於縮小如何適用於Javascript或CSS文件。 –