AutoHotkey Homepage AutoHotkey Community
Let's help each other out
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Flipping text string like Edxor

 
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help
View previous topic :: View next topic  
Author Message
arsan



Joined: 02 Jan 2010
Posts: 105

PostPosted: Tue Mar 16, 2010 10:53 am    Post subject: Flipping text string like Edxor Reply with quote

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
View user's profile Send private message
Leef_me



Joined: 08 Apr 2009
Posts: 5334
Location: San Diego, California

PostPosted: Thu Mar 18, 2010 2:13 pm    Post subject: Reply with quote

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
View user's profile Send private message
sinkfaze



Joined: 18 Mar 2008
Posts: 5043
Location: the tunnel(?=light)

PostPosted: Thu Mar 18, 2010 3:21 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
jethrow



Joined: 24 May 2009
Posts: 1907
Location: Iowa, USA

PostPosted: Thu Mar 18, 2010 3:46 pm    Post subject: Reply with quote

@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
}

_________________
Very Happy - in case I forgot to smile
Basic Webpage Controls
COM Object Reference
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
sinkfaze



Joined: 18 Mar 2008
Posts: 5043
Location: the tunnel(?=light)

PostPosted: Thu Mar 18, 2010 3:59 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail
jethrow



Joined: 24 May 2009
Posts: 1907
Location: Iowa, USA

PostPosted: Thu Mar 18, 2010 4:08 pm    Post subject: Reply with quote

Yes, you are right. I need to learn this Unicode stuff sometime Wink :
Code:
Flip(Str) {
    DllCall("msvcrt\_" ( A_IsUnicode ? "wcs" : "str" ) "rev", "UInt",&Str, "CDecl")
    return Str
}

_________________
Very Happy - in case I forgot to smile
Basic Webpage Controls
COM Object Reference
Back to top
View user's profile Send private message Visit poster's website Yahoo Messenger
arsan



Joined: 02 Jan 2010
Posts: 105

PostPosted: Thu Mar 18, 2010 4:16 pm    Post subject: Reply with quote

@Leef_me:
Wow, my friend. Thanks. Very Happy

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 Exclamation 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. Very Happy

@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
View user's profile Send private message
Leef_me



Joined: 08 Apr 2009
Posts: 5334
Location: San Diego, California

PostPosted: Thu Mar 18, 2010 6:42 pm    Post subject: Reply with quote

arsan wrote:
@Leef_me:
Wow, my friend. Thanks. Very Happy

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 {} Smile


>>It seems as if I had been busy building ladder-steps since I didn't know about the already existing super-fast elevator Exclamation 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 Rolling Eyes

>>Thanks again mate. With your help, everything about what I had been trying to figure out by experimentation has become instantly clear. Very Happy

He shoots, he scores! Everybody wins Exclamation
Back to top
View user's profile Send private message
arsan



Joined: 02 Jan 2010
Posts: 105

PostPosted: Fri Mar 19, 2010 2:37 am    Post subject: Reply with quote

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
View user's profile Send private message
nick



Joined: 24 Aug 2005
Posts: 549
Location: Berlin / Germany

PostPosted: Fri Mar 19, 2010 4:40 pm    Post subject: Reply with quote

Code:
flippedString .= Chr((0xff^Asc(A_LoopField))+1)

_________________
nick Wink
Back to top
View user's profile Send private message
Leef_me



Joined: 08 Apr 2009
Posts: 5334
Location: San Diego, California

PostPosted: Fri Mar 19, 2010 8:17 pm    Post subject: Reply with quote

nick wrote:
Code:
flippedString .= Chr((0xff^Asc(A_LoopField))+1)

Why Question
Back to top
View user's profile Send private message
nick



Joined: 24 Aug 2005
Posts: 549
Location: Berlin / Germany

PostPosted: Sat Mar 20, 2010 5:49 am    Post subject: Reply with quote

... because AHK does not support Chr(0), so the valid character ÿ (255) would be destroyed.
_________________
nick Wink
Back to top
View user's profile Send private message
arsan



Joined: 02 Jan 2010
Posts: 105

PostPosted: Sat Mar 20, 2010 8:21 am    Post subject: Reply with quote

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. Very Happy
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    AutoHotkey Community Forum Index -> Ask for Help All times are GMT
Page 1 of 1

 
Jump to:  
You can post new topics in this forum
You can reply to topics in this forum


Powered by phpBB © 2001, 2005 phpBB Group