 |
AutoHotkey Community Let's help each other out
|
| View previous topic :: View next topic |
| Author |
Message |
arsan
Joined: 02 Jan 2010 Posts: 105
|
Posted: Tue Mar 16, 2010 10:53 am Post subject: Flipping text string like Edxor |
|
|
Edxor editor has a text flipping function (Format -> Flip) by which every character is flipped. First time text is flipped to unreadable text, next time it is flipped back to readable. The process is very reliable and no data loss occurs upon repeated flipping.
I've attempted to recreate the same function here:
| Code: | ; Flip string like Edxor
string = NBC ; Start with NBC to get ±½¼ AND VICE-VERSA
flippedString =
Loop, parse, string
{
curCharAscii := Asc(A_LoopField) ; get the ascii value of current character
; get the binary equivalent of this ascii value ; Thanks to Laszlo for the method
VarSetCapacity(curCharBinary, 65, 0)
DllCall("msvcrt\_i64toa", Int64, curCharAscii, Str, curCharBinary, Int, 2)
; ensure that curCharBinary contains 8 chars, use 0 padding on left if necessary
curCharBinary := SubStr("00000000" . curCharBinary, -7) ; see help for SetFormat
; invert each binary digit in curCharBinary
curCharBinaryInverted =
Loop, parse, curCharBinary
curCharBinaryInverted .= A_LoopField = 0 ? 1 : 0
; now convert this inverted binary number to decimal ; Thanks to Laszlo for the method
invertedDecimal := DllCall("msvcrt\_strtoui64", Str, curCharBinaryInverted, Uint, 0, Int, 2, "CDECL Int64")
; now get ascii char of this (inverted) decimal number
invertedAscii := Chr(invertedDecimal)
;MsgBox, %A_LoopField% %curCharAscii% %curCharBinary% %curCharBinaryInverted% %invertedDecimal% %invertedAscii%
flippedString .= invertedAscii
}
MsgBox, %string% changed to %flippedString%
|
The procedure I use can be understood by reading the comments. But I think the process can be made shorter and faster. I'm having difficulty understanding the bitwise operations, base conversions etc. Can anyone look into it and suggest ways to make it shorter / faster?
I posted example of its use at http://www.autohotkey.com/forum/viewtopic.php?t=4391&postdays=0&postorder=asc&start=45 but that does not seem to be a proper place to ask about this. So I'm posting it here. |
|
| Back to top |
|
 |
Leef_me
Joined: 08 Apr 2009 Posts: 5334 Location: San Diego, California
|
Posted: Thu Mar 18, 2010 2:13 pm Post subject: |
|
|
replace this
| Code: |
curCharAscii := Asc(A_LoopField) ; get the ascii value of current character
; and everything in between
invertedAscii := Chr(invertedDecimal) |
with this
| Code: | | invertedAscii:=Chr(0xff^Asc(A_LoopField)) |
|
|
| Back to top |
|
 |
sinkfaze
Joined: 18 Mar 2008 Posts: 5043 Location: the tunnel(?=light)
|
Posted: Thu Mar 18, 2010 3:21 pm Post subject: |
|
|
A much easier way:
| Code: | var=Watch this string get flipped, too!
MsgBox % "Watch this string get flipped!"
. "`n" Flip("Watch this string get flipped!")
MsgBox % var "`n" Flip(var)
Flip(Str) {
DllCall("msvcrt\_strrev", "UInt",&Str, "CDecl")
return Str
} |
_________________ Try Quick Search for Autohotkey or see the tutorial for newbies. |
|
| Back to top |
|
 |
jethrow
Joined: 24 May 2009 Posts: 1907 Location: Iowa, USA
|
Posted: Thu Mar 18, 2010 3:46 pm Post subject: |
|
|
@sinkfaze - have you tried that function with the newest version of AHKL? Doesn't seem to work for me. I started using Lexikos' other example from that post: | Code: | Flip(in) {
VarSetCapacity(out, n:=StrLen(in))
Loop %n%
out .= SubStr(in, n--, 1)
return out
} |
_________________
- in case I forgot to smile
Basic Webpage Controls
COM Object Reference |
|
| Back to top |
|
 |
sinkfaze
Joined: 18 Mar 2008 Posts: 5043 Location: the tunnel(?=light)
|
Posted: Thu Mar 18, 2010 3:59 pm Post subject: |
|
|
Haven't tried it yet but I'm guessing for compatability purposes with AHK_L you can't merely call for string manipulation. Try this:
| Code: | Flip(Str) {
DllCall("msvcrt\_wcsrev", "UInt",&Str, "CDecl")
return Str
} |
EDIT: I tested this and it should work. _________________ Try Quick Search for Autohotkey or see the tutorial for newbies. |
|
| Back to top |
|
 |
jethrow
Joined: 24 May 2009 Posts: 1907 Location: Iowa, USA
|
Posted: Thu Mar 18, 2010 4:08 pm Post subject: |
|
|
Yes, you are right. I need to learn this Unicode stuff sometime : | Code: | Flip(Str) {
DllCall("msvcrt\_" ( A_IsUnicode ? "wcs" : "str" ) "rev", "UInt",&Str, "CDecl")
return Str
} |
_________________
- in case I forgot to smile
Basic Webpage Controls
COM Object Reference |
|
| Back to top |
|
 |
arsan
Joined: 02 Jan 2010 Posts: 105
|
Posted: Thu Mar 18, 2010 4:16 pm Post subject: |
|
|
@Leef_me:
Wow, my friend. Thanks.
So the code has been reduced to:
| Code: | ; Flip string like Edxor
string = NBC ; Start with NBC to get ±½¼ AND VICE-VERSA
flippedString =
Loop, parse, string
{
invertedAscii:=Chr(0xff^Asc(A_LoopField))
flippedString .= invertedAscii
}
MsgBox, %string% changed to %flippedString%
|
It seems as if I had been busy building ladder-steps since I didn't know about the already existing super-fast elevator But I guess I learnt some new concepts doing it.
By the way, I was busy experimenting with xor myself. Here's what I wrote in my attempt to teach myself about it:
| Code: | ; Demonstration of xor ie, a ^ b
; It converts a and b to their binary equivalents, xor those binary numbers, and converts the result back to decimal
a = 100
b = 300
xorResult := a ^ b
; get the binary equivalents
VarSetCapacity(a_binary, 65, 0)
DllCall("msvcrt\_i64toa", Int64, a, Str, a_binary, Int, 2)
VarSetCapacity(b_binary, 65, 0)
DllCall("msvcrt\_i64toa", Int64, b, Str, b_binary, Int, 2)
VarSetCapacity(xorResult_binary, 65, 0)
DllCall("msvcrt\_i64toa", Int64, xorResult, Str, xorResult_binary, Int, 2)
; zero-pad each binary number to 16 digits (good upto 65535, binary 1111111111111111)
zeroPad := "0000000000000000"
a_binary := SubStr(zeroPad . a_binary, -15)
b_binary := SubStr(zeroPad . b_binary, -15)
xorResult_binary := SubStr(zeroPad . xorResult_binary, -15)
; now check yourself whether the xor result is correct or not
MsgBox,
(
a = %a% bin %a_binary%
b = %b% bin %b_binary%
a ^ b = %xorResult% bin %xorResult_binary%
) |
Thanks again mate. With your help, everything about what I had been trying to figure out by experimentation has become instantly clear.
@sinkfaze:
Thanks for your help pal. Your function flips and flips back text properly without data loss and that is what matters most. I don't understand DllCalls yet but one of these days I am going to start reading and experimenting upon it. So I'm saving your script now to study later.
One thing I failed to mention in my first post that by flipping text I meant bit-wise inversion of every character - the process that I used for that can be read in my comments in the first post. I just used the term "flip" as it was used in Edxor. The output of your function is something different. But one of these days I will figure it out. |
|
| Back to top |
|
 |
Leef_me
Joined: 08 Apr 2009 Posts: 5334 Location: San Diego, California
|
Posted: Thu Mar 18, 2010 6:42 pm Post subject: |
|
|
| arsan wrote: | @Leef_me:
Wow, my friend. Thanks.
So the code has been reduced to:
| Code: | ; Flip string like Edxor
string = NBC ; Start with NBC to get ±½¼ AND VICE-VERSA
flippedString =
Loop, parse, string
{
invertedAscii:=Chr(0xff^Asc(A_LoopField))
flippedString .= invertedAscii
}
MsgBox, %string% changed to %flippedString%
|
|
You are welcome. btw, you can probably reduce that to 1 line of code inside the {} and then throw away the {}
>>It seems as if I had been busy building ladder-steps since I didn't know about the already existing super-fast elevator But I guess I learnt some new concepts doing it.
Everybody's gotta learn to crawl, and sometimes the 'long form' is actually easier to document/understand/whatever.
By the way, I was busy experimenting with xor my>>self. Here's what I wrote in my attempt to teach myself about it:
Speaking of crawling, I think I'll crawl away from DLL
>>Thanks again mate. With your help, everything about what I had been trying to figure out by experimentation has become instantly clear.
He shoots, he scores! Everybody wins  |
|
| Back to top |
|
 |
arsan
Joined: 02 Jan 2010 Posts: 105
|
Posted: Fri Mar 19, 2010 2:37 am Post subject: |
|
|
| Leef_me wrote: | | you can probably reduce that to 1 line of code inside the {} and then throw away the {} |
Of course, and also throw away a variable alongwith the {} like this:
| Code: | ; Flip string like Edxor
string = NBC ; Start with NBC to get ±½¼ AND VICE-VERSA
flippedString =
Loop, parse, string
flippedString .= Chr(0xff^Asc(A_LoopField))
MsgBox, %string% changed to %flippedString% |
|
|
| Back to top |
|
 |
nick
Joined: 24 Aug 2005 Posts: 549 Location: Berlin / Germany
|
Posted: Fri Mar 19, 2010 4:40 pm Post subject: |
|
|
| Code: | | flippedString .= Chr((0xff^Asc(A_LoopField))+1) |
_________________ nick  |
|
| Back to top |
|
 |
Leef_me
Joined: 08 Apr 2009 Posts: 5334 Location: San Diego, California
|
Posted: Fri Mar 19, 2010 8:17 pm Post subject: |
|
|
| nick wrote: | | Code: | | flippedString .= Chr((0xff^Asc(A_LoopField))+1) |
|
Why  |
|
| Back to top |
|
 |
nick
Joined: 24 Aug 2005 Posts: 549 Location: Berlin / Germany
|
Posted: Sat Mar 20, 2010 5:49 am Post subject: |
|
|
... because AHK does not support Chr(0), so the valid character ÿ (255) would be destroyed. _________________ nick  |
|
| Back to top |
|
 |
arsan
Joined: 02 Jan 2010 Posts: 105
|
Posted: Sat Mar 20, 2010 8:21 am Post subject: |
|
|
Thanks nick. You're right. Here's a script that I wrote to test whether a character, which if flipped and flipped back, matches or not:
| Code: | ; generate ascii table
; decimal > asciiChar > flippedAsciiChar > flippedBack2AsciiChar
; compare ascii character to flippedBack2Ascii character
#NoEnv
#SingleInstance, ignore
decimalValue = 0
output =
While, decimalValue <= 255
{
char := Chr(decimalValue)
flippedChar := flip(char)
flippedDec := Asc(flippedChar)
flippedBackChar := flip(flippedChar)
If (char = flippedBackChar)
testCheck = OK
Else
{
testCheck = Failed
MsgBox, %decimalValue% %char% flip mismatch. ; prompt in case of mismatch
}
output .= decimalValue . "`t" . char . "`t" . flippedChar . "`t" . flippedBackChar . "`t" . flippedDec . "`t" . testCheck . "`n"
decimalValue++
}
; Examine the output file manually
FileAppend, %output%, ascii.txt
flip(string)
{
flippedString =
Loop, parse, string
;flippedString .= Chr(0xff^Asc(A_LoopField)) ; Leef_me expression
flippedString .= Chr((0xff^Asc(A_LoopField))+1) ; nick expression
Return, %flippedString%
} |
Run the code two times - in case of data mismatch, there will be a prompt.
1. first time - comment the brown line, run code and rename output to ascii1.txt
2. second time - comment the red line, run code and compare the output ascii.txt to the previous output ascii1.txt with a file comparing tool like Beyond Compare or other similar tool.
Nick's expression makes the output incompatible to Edxor's output but won't result in any data loss upon flipping and flipping back strings which contain character with ascii code 255 (hex 0xff).
A big THANKS to both of you again for your help.  |
|
| Back to top |
|
 |
|
|
You can post new topics in this forum You can reply to topics in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|