AutoHotkey Community

It is currently May 27th, 2012, 2:58 am

All times are UTC [ DST ]




Post new topic Reply to topic  [ 13 posts ] 
Author Message
PostPosted: March 16th, 2010, 11:53 am 
Offline

Joined: January 2nd, 2010, 6:13 pm
Posts: 105
Edxoreditor 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.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 3:13 pm 
Offline

Joined: April 8th, 2009, 7:49 pm
Posts: 6071
Location: San Diego, California
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))


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 4:21 pm 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5480
Location: the tunnel(?=light)
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
}

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 4:46 pm 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
@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
}

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 4:59 pm 
Offline
User avatar

Joined: March 19th, 2008, 12:43 am
Posts: 5480
Location: the tunnel(?=light)
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.

_________________
Image
Try Quick Search for Autohotkey or see the tutorial for newbies.


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 5:08 pm 
Offline
User avatar

Joined: May 24th, 2009, 5:35 am
Posts: 2099
Location: Iowa, USA
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
}

_________________
Image
Recommended: AutoHotkey_L
Basic Webpage Controls


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 5:16 pm 
Offline

Joined: January 2nd, 2010, 6:13 pm
Posts: 105
@Leef_me:
Wow, my friend. Thanks. :D

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. :D

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


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 18th, 2010, 7:42 pm 
Offline

Joined: April 8th, 2009, 7:49 pm
Posts: 6071
Location: San Diego, California
arsan wrote:
@Leef_me:
Wow, my friend. Thanks. :D

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 :roll:

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

He shoots, he scores! Everybody wins :!:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 19th, 2010, 3:37 am 
Offline

Joined: January 2nd, 2010, 6:13 pm
Posts: 105
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%


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 19th, 2010, 5:40 pm 
Offline

Joined: August 24th, 2005, 5:29 pm
Posts: 549
Location: Berlin / Germany
Code:
flippedString .= Chr((0xff^Asc(A_LoopField))+1)

_________________
nick :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 19th, 2010, 9:17 pm 
Offline

Joined: April 8th, 2009, 7:49 pm
Posts: 6071
Location: San Diego, California
nick wrote:
Code:
flippedString .= Chr((0xff^Asc(A_LoopField))+1)

Why :?:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2010, 6:49 am 
Offline

Joined: August 24th, 2005, 5:29 pm
Posts: 549
Location: Berlin / Germany
... because AHK does not support Chr(0), so the valid character ÿ (255) would be destroyed.

_________________
nick :wink:


Report this post
Top
 Profile  
Reply with quote  
 Post subject:
PostPosted: March 20th, 2010, 9:21 am 
Offline

Joined: January 2nd, 2010, 6:13 pm
Posts: 105
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. :D


Report this post
Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 13 posts ] 

All times are UTC [ DST ]


Who is online

Users browsing this forum: Bing [Bot], rbrtryn and 27 guests


You can post new topics in this forum
You can reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Powered by phpBB® Forum Software © phpBB Group