Skip to content

Instantly share code, notes, and snippets.

@kernelsmith
Last active February 21, 2023 19:57
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save kernelsmith/6691018 to your computer and use it in GitHub Desktop.
Save kernelsmith/6691018 to your computer and use it in GitHub Desktop.
Ruby tricks, tips, and one-linersConvert hex data to hex string, convert file contents to base64, machine sortable, but still human-readable time stamps, mash two arrays into a hash where one array is hash keys (esp CSV parsing), timeouts, zip files
#
# One-liners (or one'ish-liners)
#
pry(main)> Psych::VERSION
=> "3.1.0"
pry(main)> show-source Psych
=> # lots of code
pry(main)> show-method meth_name
# From: /home/some_code.rb:233:
# Owner: Class
# Visibility: public
# Signature: meth_name()
# Number of lines: 6
def meth_name
return nil # blah blah
end
# remove all gem documentation (from shell):
rm -rf "$(gem env gemdir)"/doc/*
### CONVERT a hex file to hex string
# for_testing$ echo -n "DEADBEEFDEADBEEF" > tmp
File.open("tmp", "rb") {|f| [f.read].pack("H*")}
# => "\xDE\xAD\xBE\xEF\xDE\xAD\xBE\xEF"
### CONVERT to base64 (note .encode and .strict_encode can have different results)
require 'base64' and File.open("tmp", "rb") {|f| Base64.strict_encode64(f.read)}
# => "REVBREJFRUZERUFEQkVFRg==\n"
### sweet TIMESTAMP, nicely formatted & machine sortable, good for file names esp the 2nd one.
require 'time' # yes this is required. To access the .utc method iirc
Time.now.utc.iso8601 # => "2013-03-27T21:40:19Z"
Time.now.utc.iso8601.gsub(':','-') # => "2013-03-27T21-40-19Z"
### one line WEBSERVER, like python -m SimpleHTTPServer port
ruby -run -e httpd -- [-p port] DocumentRoot
### CONVERT 2 ARRAYS TO A HASH
a1 = [1,2,3]
a2 = ["one", "two", "three"]
h = Hash[a1.zip(a2)]
# => {1=>"one", 2=>"two", 3=>"three"}
# or as a true one-liner, tho more confusing:
Hash[ [1,2,3].zip(["one", "two", "three"]) ]
# this is especially useful when you are reading lines from a file, like a CSV file and want to map items to the column title:
rows_as_hashes = []
columns = [:last, :first, :age]
CSV.read_lines do |line|
rows_as_hashes << Hash[ columns.zip(line) ] # <= {:age=>69, :first=>"James", :last=>"Smith"} etc.
end
#
# Tips & Tricks
#
### basic usage of timeouts
require 'timeout'
timeout = 10 # in seconds
buffer = ''
io = SomeFakeIo.new
begin
Timeout.timeout(timeout) do
ret = nil
# do stuff that might timeout
io.read
end
return ret
rescue ::Timeout::Error #, Rex::TimeoutError as well if Metasploit (lib/rex/exceptions.rb)
puts "Timeout Error message"
return nil
rescue ::OtherException => e
raise e
ensure
io.close if io
end
### create zip files in memory
# credit: http://www.devinterface.com/blog/en/2010/02/create-zip-files-on-the-fly/
def create_zip(file_list, filename = nil, &block)
if !file_list.blank?
# require 'time' is assumed from above
stamp = Time.now.utc.iso8601.gsub(':','-') || "tmp"
filename ||= "#{stamp}.zip"
Tempfile.open(stamp) do |t|
Zip::ZipOutputStream.open(t.path) do |z|
file_list.each do |f|
z.put_next_entry(f)
z.print IO.read(f) # this could use some error handling
end
end
# Do something with t now. If you're emailing this from Rails you can:
#send_file t.path, :type => 'application/zip',:disposition => 'attachment',:filename => file_name
# But I want to save it to disk, we can use a block form
if block_given?
yield t
else
end
end
end
# convert ascii string into 4-byte hex string groupings like "0x41424345"
# highest nibble first
s = "string";s.unpack('H*').first.scan(/[0-9A-Fa-f]{1,8}/).map {|i| "0x#{i}"}.join(" ")
# this could be improved in many ways.
@kernelsmith
Copy link
Author

The zip thing needs work

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment