如何缩小Ruby源文件? [英] How can I minify a Ruby source file?

查看:110
本文介绍了如何缩小Ruby源文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a situation where I'd like to be able to minify (not compile) a Ruby script. The goals are to:

  1. 减少脚本的总字符数;
  2. 进行某种程度的混淆,使其他人难以修改代码.

我们可以假设:

  1. 是的,我知道我在做什么,并且我确实确实想最小化和混淆代码.
  2. 原始Ruby代码具有简单的语法,并且不使用任何高级元编程技术等.

是否存在用于此目的的任何现有库或工具?如果不是,那么开始开发一个简单的minifier(理想情况下也是用Ruby编写)的最佳方法是什么?

Is there any existing library or tool for this? If not, what would be the best way to get started to develop a simple minifier (ideally, also written in Ruby)?

推荐答案

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

I created a simple script that reads a Ruby file, generates a minified and obfuscated version, and then interprets the output to regenerate it again. I created a Ruby file and used command expansion to run a Shell script that may be executed with ruby 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

我编写了Shell脚本,该脚本接受一个输入Ruby源文件并根据输入生成一个输出文件. (可选)您可以直接使用sh main.sh来运行它(而不是使用为RSpec测试而添加的main.rb包装器).请注意,存储库中共享的大多数main.sh代码如下所示,但为简洁起见,我省略了recover_source函数的详细信息,该函数尝试在第二个输出文件中重新生成原始Ruby源文件.

I wrote the Shell script, which takes an input Ruby source file and generates an output file based on the input. Optionally you can just run this directly with with sh main.sh (instead of using the main.rb wrapper that I added for testing with RSpec). Note that most of the main.sh code shared in the repository is shown below, but for brevity I have omitted details of the recover_source function, which tries to re-generate the original Ruby source file in a second output file.

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

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

The example source code file I used is shown below:

require 'bigdecimal'

class Obfiscate
    include Comparable

  attr_reader :name

  def initialize(name)
    @name = name
  end
end

它通过反转源文件中的每一行来进行一定程度的混淆,并使用正则表达式用我自己的自定义缩写替换Ruby语法(即,将require替换为*r*,将class替换为*c**ar*def*d*end*e*)来减少整体字符数,并可以选择删除空白行,如下面的示例输出所示:

It applies a degree of obfuscation by reversing each line in the source file and uses regular expressions replace Ruby syntax with my own custom abbreviations (i.e. replace require with *r*, class with *c*, attr_accessor with *ar*, def with *d*, and end with *e*) to reduce the overall character count and optionally remove blank lines as shown in sample output below:

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

这篇关于如何缩小Ruby源文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆