Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom Character sets #25

Open
frnco opened this issue Jul 30, 2020 · 1 comment
Open

Custom Character sets #25

frnco opened this issue Jul 30, 2020 · 1 comment
Labels
feature request New feature request or suggestion

Comments

@frnco
Copy link

frnco commented Jul 30, 2020

I am surprised by how great TMatrix's output is, the gradient looks amazing, and I think another good feature would be giving more control on which characters are shown.

The idea comes from will8211/unimatrix and the implementation there is actually very simple, there are two command-line parameters, one for predetermined charsets and other for custom characters. I believe even just one of the two strategies would already be a good additioon to TMatrix, and sooner or later I'll probably implement this to some extent even if just for me to use it, so I may be able to send a PR.

The implementation on Unimatrix is pretty simple:

First there's an Object/Hash/etc with the predefined charsets:

char_set = {
    'a': 'qwertyuiopasdfghjklzxcvbnm',
    'A': 'QWERTYUIOPASDFGHJKLZXCVBNM',
    'c': 'абвгдежзиклмнопрстуфхцчшщъыьэюя',
    'C': 'АБВГДЕЖЗИКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ',
    'e': '☺☻✌♡♥❤⚘❀❃❁✼☀✌♫♪☃❄❅❆☕☂★',
    'g': 'αβγδεζηθικλμνξοπρστυφχψως',
    'G': 'ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩ',
    'k': 'ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン',
    'm': 'ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン1234567890'
         '1234567890-=*_+|:<>"-=*_+|:<>"-=*_+|:<>"-=*_+|:<>"',
    'n': '1234567890',
    'o': 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890'
         '`-=~!@#$%^&*()_+[]{}|\;\':",./<>?"',
    'p': '',
    'P': '',
    'r': 'mcclllxxxxvvvvviiiiii',
    'R': 'MCCLLLXXXXVVVVVIIIIII',
    's': '-=*_+|:<>"',
    'S': '`-=~!@#$%^&*()_+[]{}|\;\':",./<>?"',
    'u': args.custom_characters}

Then for the charsets option just concatenate the characters for each specified Charset into a Variable with all possible characters. And to make things even simpler, the custom characters passed through the parameter are saved as one of the charsets:

# "-l" option has been used
if args.character_list:
    chars = ''
    for letter in args.character_list:
        try:
            chars += char_set[letter]
        except KeyError:
            print("Letter '%s' does not represent a valid character list."
                  % letter)
            exit()

And just pick a random character from the all-possible-characters variable to display:

@staticmethod
def get_char():
    """
    Returns a random character from the active character set
    """
    return chars[randint(0, chars_len)]

This has the advantage of specifying not only which characters are available but also how common or rare each character is.

I'd probably use a lambda for the "m" charset and maybe using a lambda or something to generate charsets in a cleaner way

In Ruby (which is my go-to language) for instance, I can do stuff like this:

irb(main):019:0> puts ("A".."z").to_a.join.concat (0..9).to_a.join
ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz0123456789

So putting that together with my love for hackish stuff, I'd most likely consider taking arguments formatted as something like:

--custom="0..9,A..Z, ,a..z,12345"

...so I could do this kinda madness:

irb(main):009:1* "0..9,A..Z, ,a..z,12345".split(",").map{|i| 
irb(main):010:1*   next i.to_s unless i.match? /^.\.\..$/
irb(main):011:1*   i.split("..").inject{|f,l|(f..l).to_a.join}
irb(main):012:0> }.join
=> "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz12345"

Or the slightly more readable and less quirky:

irb(main):014:0> input = "0..9,A..Z, ,a..z,12345"
irb(main):015:1* input.split(",").map{|item|
irb(main):016:2*   if item.match? /^.\.\..$/
irb(main):017:2*     item.split("..").inject{|first,last|(first..last).to_a.join}
irb(main):018:2*   else
irb(main):019:2*     item.to_s 
irb(main):020:1*   end
irb(main):021:0> }.join
=> "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz12345"

Pretty neat for less than 10 lines of code, if I do say so myself... And I think this covers pretty much everything I might want.

@M4444
Copy link
Owner

M4444 commented Aug 2, 2020

Thanks! Adding custom characters might be useful for some people. I'll take a look at it.

@M4444 M4444 added the feature request New feature request or suggestion label Aug 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature request New feature request or suggestion
Projects
None yet
Development

No branches or pull requests

2 participants