简体   繁体   中英

How can I replace a character in of the middle of a string with a random character?

I am checking the values of a string that is a unique identifier for a third party service that has some strict rules about the identifier, if a duplicate is generated I need to catch it and replace a character to make it unique. The Rules: It must be a string, it must be <= 21 characters long, the last four characters are significant and come preset and can't be altered, the first 15 characters are significant come preset and can't be altered, so I only have two characters that I can alter, and finally another third party system sets the string and will gladly duplicate them if the circumstances are right. They're always right. like. always... lol

At first I thought of using str.next! but that violates the last four rule. Then I tried str.insert(-5, rand(9).to_s) That would alter one of the correct characters and make the string unique, but it violates the <=21 characters rule.

str = "abcdefghijklmnoXX_123" (I can safely alter the XX)
str.next! (makes it unique but violates last four rule)
str.insert(-5, rand(9).to_s) (alters the correct characters and makes it unique, but violates the str.length rule.  

How can I replace the correct character set without altering the string length or violating any further rules? Oh, It is also preferred that I not shorten the string length if possible.

Clearest for me would be something like:

prefix = str[0..14]
middle = str[15..17]
suffix = str[18..-1]
unique_id = prefix + middle.next + suffix

If I understand right.

I have assumed that the characters being replaced do not have to be random, but simply different from each other and different from all of the other characters in the string. If they are for some reason to be selected randomly, further specificity is required, specifically the collection of characters from which characters are to be drawn randomly. I have a further comment on this at the end of my answer.

REQD_BEGIN = 15
REQD_END = 4
PERMITTED_CHARS = ('a'..'z').to_a.join
  #=> "abcdefghijklmnopqrstuvwxyz"

str = "abcdefrqsjklmnoXX_123"

nbr_replacements = str.size - REQD_BEGIN - REQD_END
  #=> 2 
available_chars =
  PERMITTED_CHARS.delete(str[0,REQD_BEGIN].downcase +
    str[-REQD_END, REQD_END].downcase)
  #=> "ghiptuvwxyz" 
str[0, REQD_BEGIN] + available_chars[0, nbr_replacements] +
  str[-REQD_END, REQD_END] 
  #=> "abcdefrqsjklmnogh_123"

This does not modify ("mutate) str . To mutate the string, change the last line to:

s[REQD_BEGIN, nbr_replacements] = available_chars[0, nbr_replacements]
  #=> "gh" 

Now:

s #=> "abcdefrqsjklmnogh_123"  

If the replacement characters are to be selected randomly (but satisfy the uniqueness properties set out at the onset), the constant PERMITTED_CHARS would be set equal to a string containing the characters from which a random sample would be drawn. available_chars would be computed as now, but available_chars[0, nbr_replacements] would be changed to available_chars.sample(nbr_replacements) .

By using the string_pattern gem: https://github.com/MarioRuiz/string_pattern

require 'string_pattern'
str = "abcdefghijklmnoXX_123"
new_str = str[0..14] + "2:L".gen + str[17..20]

#or also like this
new_str = [str[0..14], "2:L", str[17..20]].gen

And if you want to generate always unique so don't repeat ever the string while the execution is on then add to the string pattern & at the end:

# one unique string during the whole execution
new_str = [str[0..14], "2:L&", str[17..20]].gen

# generate 100 unique strings and store them on an array
unique_strings = []
100.times do
  unique_strings << [str[0..14], "2:L&", str[17..20]].gen
end

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM