How to check if string is SecureRandom.urlsafe_base64(64) - ruby-on-rails

The string:
SecureRandom.urlsafe_base64(64)
#=> "nItIZhCvbne9zjU4JUWJOL46y53ERfmuQQW_FN4_ymk2EdbQr1NYOXTJVIeUWXhvRCe4OU3Is2ZEaHpiXXGYxw"
Random::Formatted.urlsafe_base64 implementation:
def urlsafe_base64(n=nil, padding=false)
s = [random_bytes(n)].pack("m0")
s.tr!("+/", "-_")
s.delete!("=") unless padding
s
end
So the question is basically what title says: is there a sane way to check whether string is generated with above method?
Maybe with some regexp? From docs:
The result may contain A-Z, a-z, 0-9, “-” and “_”. “=” is also used if
padding is true.
I would think there is not, because string is just a string, but I need to know if I can rely on anything more than its length while checking it.
Initial problem is that Rollbar gem filters API request Header with ***, and I'd like to change that so that I can see first n characterss of api token to track who made the failing request.

I'm gonna answer the literal question:
is there a sane way to check whether string is generated with above method?
Yes, there is. Kind of. Depends on where your boundaries of "sane" are. :)
Adapted from http://www.schneems.com/2016/01/25/ruby-debugging-magic-cheat-sheet.html
require 'objspace'
require 'securerandom'
ObjectSpace.trace_object_allocations_start
Kernel.send(:define_method, :sup) do |obj|
puts "#{ ObjectSpace.allocation_sourcefile(obj) }:#{ ObjectSpace.allocation_sourceline(obj) }"
end
str = SecureRandom.urlsafe_base64(64)
sup str
# >> /Users/sergio/.rubies/ruby-2.3.3/lib/ruby/2.3.0/securerandom.rb:169

Related

check if string is base64

i may recieve these two strings:
base = Base64.encode64(File.open("/home/usr/Desktop/test", "rb").read)
=> "YQo=\n"
string = File.open("/home/usr/Desktop/test", "rb").read
=> "a\n"
what i have tried so far is to check string with regular expression i-e. /([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==$)/ but this would be very heavy if the file is big.
I also have tried base.encoding.name and string.encoding.name but both returns the same.
I have also seen this post and got regular expression solution but any other solution ?
Any idea ? I just want to get is the string is actually text or base64 encoded text....
You can use something like this, not very performant but you are guaranteed not to get false positives:
require 'base64'
def base64?(value)
value.is_a?(String) && Base64.strict_encode64(Base64.decode64(value)) == value
end
The use of strict_encode64 versus encode64 prevents Ruby from inadvertently inserting newlines if you have a long string. See this post for details.

How can you allow <3 or any tag < any character not ending with < or > sanitize

sanitize("hello") => hello
but if I have
sanitize("<3") it return 3 only
I want it should allow string if not end with < or >
like if I do
sanitize("<3 >4") it should simply return <3 >4
First off, Rails' built-in sanitize doesn't deal with malformed markup.
I highly recommend you use the Sanitize gem for dealing with anything that could potentially be malformed:
https://github.com/rgrove/sanitize
But your issue is non-html-encoded character entities. Run them through CGI.escape()
require 'cgi'
CGI.escape('<3') # => "%3C3"
For the finish:
require 'cgi'
Sanitize.clean( CGI.escape('<3') ) # => "%3C3"
You should do a pre-clean on your content to properly encode values you want to preserve. For example:
content.gsub!(/\<3/, '<3')
The only concern is that your cleaner might double-escape this to &lt;3 which can prove annoying. At least that's possible to reverse if required.
It's not possible to "sanitize" without stripping invalid brackets. Some browsers will choke on that sort of thing and it can render your page entirely corrupted if not handled correctly.

Replace "%20" with "-" in URL for rails

I'm developing a web application using rails.
For aesthetic purposes, i need to replace %20 with -
Before: http://localhost:3000/movies/2006/Apna%20Sapna%20Money%20Money
After: http://localhost:3000/movies/2006/Apna-Sapna-Money-Money
Is there anyway i can achieve this in rails?
You should use URI.parse to break it into pieces and then change only the path component:
require 'uri'
u = URI.parse(url)
u.path = u.path.gsub('%20', '-')
url = u.to_s
Just a simple gsub on the whole URL would probably work fine but a little extra paranoia might save you some confusion and suffering down the road. Also, if you're just replacing a literal string rather than a regular expression, you can use a String as the first argument to gsub and avoid some escaping issues:
The pattern is typically a Regexp; if given as a String, any regular expression metacharacters it contains will be interpreted literally, e.g. '\\d' will match a backlash followed by d, instead of a digit.
If your string is stored in the variable url you can use
url.gsub(/%20/, "-")
to return the string you want, or
url.gsub!(/%20/, "-")
to actually modify the value of url with the value you want.
https://github.com/FriendlyId/friendly_id
this is the best way to go about seo urls
You probably want to be saving "Apna-Sapna-Money-Money" within your Movies model as an attribute (I usually call these slugs). Then, to generate these, you might just need to replace spaces in the movie title with hyphens. Something like:
class Movie
before_create :generate_slug
private
def generate_slug
slug = title.gsub(" ", "-")
end
end
Then in your controller action you can simply do a Movie.find_by_slug!(params[:id]) call.
Basically, there should be no reason for users to ever arrive at a URL with %20 in it...

Stripping the first character of a string

i have
string = "$575.00 "
string.to_f
// => 0.0
string = "575.00 "
string.to_f
// => 575.0
the value coming in is in this format and i need to insert into a database field that is decimal any suggestions
"$575.00 "
We did this so often we wrote an extension to String called cost_to_f:
class String
def cost_to_f
self.delete('$,').to_f
end
end
We store such extensions in config/initializers/extensions/string.rb.
You can then simply call:
"$5,425.55".cost_to_f #=> 5425.55
If you are using this method rarely, the best bet is to simply create a function, since adding functions to core classes is not exactly something I would recommend lightly:
def cost_to_f(string)
string.delete('$,').to_f
end
If you need it in more than one class, you can always put it in a module, then include that module wherever you need it.
One more tidbit. You mentioned that you need to process this string when it is being written to the database. With ActiveRecord, the best way to do this is:
class Item < ActiveRecord::Base
def price=(p)
p = p.cost_to_f if p.is_a?(String)
write_attribute(:price, p)
end
end
EDIT: Updated to use String#delete!
So many answers... i'll try to summarize all that are available now, before give own answer.
1. string.gsub(/[\$,]/, '')
string.gsub!(/^\$/, '')
2. string[1..-1]
3. string.slice(0) # => "ome string"
4. s/^.//
Why (g)sub and regexp Just for deleting a character? String#tr is faster and shorter. String#delete is even better.
Good, fast, simple. Power of reverse indexing.
Hm... looks like it returns "S". Because it is an alias to String#[]
Perl? /me is cheking question tags...
And my advice is:
What if you have not dollar, but yena? Or what if you don't even have anything before numbers?
So i'll prefer:
string[/\d.+/]
This will crop leading non-decimal symbols, that prevent to_f to work well.
P.S.: By the way. It's known, that float is bad practice for storing money amounts.
Use Float or Decimal for Accounting Application Dollar Amount?
You could try something like this.
string = string[1..-1] if string.match(/^\$/)
Or this.
string.gsub!(/^\$/, '')
Remember to put that backslash in your Regexp, it also means "end of string."
you can use regex for that:
s/^.//
As laways, this is PCRE syntax.
In Ruby, you can use the sub() method of the string class to replace the string:
result = string.sub(/^./,"")
This should work.
[EDIT]
Ok, someone asked what's the gsub() is for:
gsub() acts like sub() but with the /g modifier in PCRE (for global replacement):
s/a/b/
in PCRE is
string.sub(/a/, "b")
and
s/a/b/g
is
string.gsub(/a/, "b")
in Ruby
What I'd use (instead of regular expressions) is simply the built-in slice! method in the String class. For example,
s = "Some string"
s.slice!(0) # Deletes and returns the 0th character from the string.
s # => "ome string"
Documentation here.

Best way to encode URLs?

I am currently developing a CMS and want to encode special chars in the URL in a nice way.
I don't want to use Rack::Utils.escape.
Is there already a cool gem available?
Best regards
Look at the stringex gem here, it can be used even without rails, but contains some stuff to make it easier to use(with rails).
Ruby's CGI library should do what you need:
url_encoded_string = CGI::escape("'Stop!' said Fred")
# => "%27Stop%21%27+said+Fred"
See http://ruby-doc.org/core/classes/CGI.html
Well, I normally use a handy custom-made method called String.to_slug. I hope you find it useful.
Call this /lib/to_slug.rb and include it in one initializer, or include it only on the model that generates the urls.
String.class_eval do
#converts accented letters into ascii equivalents (eg. ñ becomes n)
def normalize
#this version is in the forums but didn't work for me
#chars.normalize(:kd).gsub!(/[^\x00-\x7F]/n,'').to_s
mb_chars.normalize(:d).gsub(/[^\x00-\x7F]/n,'').to_s
end
#returns an array of strings containing the words on a string
def words
gsub(/\W/, ' ').split
end
#convert into a nice url-ish string
def to_slug(separator='-')
strip.downcase.normalize.words.join(separator)
end
end

Resources