Size: 2397
Comment: Added a faster version of chr
|
Size: 1901
Comment: Attempting to fix missing title. Removed blank line
|
Deletions are marked like this. | Additions are marked like this. |
Line 12: | Line 12: |
Line 16: | Line 17: |
Line 20: | Line 21: |
#Another version doing the octal conversion with arithmetic # faster as it avoids a subshell chr () { printf \\$(($1/64*100+$1%64/8*10+$1%8)) } |
|
Line 28: | Line 35: |
hex() { | hex() { |
Line 37: | Line 44: |
Line 41: | Line 48: |
Line 44: | Line 50: |
''Tricky? Rather, it's using a feature that I can't find documented anywhere -- putting a single quote in front of an integer. Neat effect, but how on '''earth''' did you find out about it? Source diving? -- GreyCat'' ''It validates The Single Unix Specification: "If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote." (see [[http://www.opengroup.org/onlinepubs/009695399/utilities/printf.html|printf()]] to know more) -- mjf'' This version of {{{chr}}} executes much faster than the {{{printf}}} version above (about 1/40 to less than 1/150 the time when run in a loop): {{{ chr() { echo -en "\0$(( $1 % 8 + 10 * ( $1 / 8 ) + 20 ))"; } }}} {{{ for p in chr newchr; do time for i in {1..4000}; do $p 65 >/dev/null; done; done System1 System2 real 0m46.824s real 1m33.814s user 0m4.624s user 0m8.540s sys 0m33.290s sys 1m23.978s real 0m1.340s real 0m0.512s user 0m1.096s user 0m0.389s sys 0m0.124s sys 0m0.096s }}} |
. ''Tricky? Rather, it's using a feature that I can't find documented anywhere -- putting a single quote in front of an integer. Neat effect, but how on '''earth''' did you find out about it? Source diving? -- GreyCat'' . ''It validates The Single Unix Specification: "If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote." (see [[http://www.opengroup.org/onlinepubs/009695399/utilities/printf.html|printf()]] to know more) -- mjf'' |
How do I convert an ASCII character to its decimal (or hexadecimal) value and back?
If you have a known octal or hexadecimal value (at script-writing time), you can just use printf:
# POSIX printf '\x27\047\n'
This prints two literal ' characters (27 is the hexadecimal ASCII value of the character, and 47 is the octal value) and a newline.
If you need to convert characters (or numeric ASCII values) that are not known in advance (i.e., in variables), you can use something a little more complicated:
# POSIX # chr() - converts decimal value to its ASCII character representation # ord() - converts ASCII character to its decimal value chr() { printf \\$(printf '%03o' $1) } #Another version doing the octal conversion with arithmetic # faster as it avoids a subshell chr () { printf \\$(($1/64*100+$1%64/8*10+$1%8)) } ord() { printf '%d' "'$1" } # hex() - converts ASCII character to a hexadecimal value # unhex() - converts a hexadecimal value to an ASCII character hex() { printf '%x' "'$1" } unhex() { printf \\x"$1" } # examples: chr $(ord A) # -> A ord $(chr 65) # -> 65
The ord function above is quite tricky.
Tricky? Rather, it's using a feature that I can't find documented anywhere -- putting a single quote in front of an integer. Neat effect, but how on earth did you find out about it? Source diving? -- GreyCat
It validates The Single Unix Specification: "If the leading character is a single-quote or double-quote, the value shall be the numeric value in the underlying codeset of the character following the single-quote or double-quote." (see printf() to know more) -- mjf