Skip to content

Instantly share code, notes, and snippets.

@mloughran
Created April 4, 2011 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mloughran/902183 to your computer and use it in GitHub Desktop.
Save mloughran/902183 to your computer and use it in GitHub Desktop.
Making WebSocket unmasking fast in ruby
module EventMachine
module WebSocket
class MaskedString < String
def read_mask
raise "Too short" if bytesize < 4 # TODO - change
@masking_key = String.new(self[0..3])
end
def slice_mask
slice!(0, 4)
end
def getbyte(index)
masked_char = super(index + 4)
masked_char ? masked_char ^ @masking_key.getbyte(index % 4) : nil
end
def getbytes(start_index, count)
data = ''
count.times do |i|
data << getbyte(start_index + i)
end
data
end
end
end
end
require 'benchmark'
n = 1000
# Use a 4 byte mask and a 1K string
string = rand.to_s[0..3] + 'a' * 1024
Benchmark.bm do |x|
x.report("MaskedString:") {
n.times {
string = EventMachine::WebSocket::MaskedString.new(string)
string.read_mask
string.getbytes(0, 1024)
}
}
end
@mloughran
Copy link
Author

@igrigorik
Copy link

Check dan's gists, he's getting some wins, but another thread that might be useful: http://markmail.org/message/owwxbh7v67zjo4k3#query:ruby%20string%20and%20xor+page:1+mid:4vibjcxf4r5c2prs+state:results

@igrigorik
Copy link

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