Sign in to follow this  
Followers 0
James

Scramble a string

9 posts in this topic

Hey all,

I am trying to make a UDF which will take a string and randomly move the letters.

I got this far:

;===============================================================================
;
; Description:        Scramble letters
; Parameter(s):        $io_text = text to scramble
;
; Requirement:        3.2.6.0
; Return Value(s):    [0] = full text
; User CallTip:
; Author(s):        James Brooks aka JamesB
; Note(s):
;===============================================================================

#include-once
#include <String.au3>

Func _StringScramble($io_text, $io_reverse = True)
    Local $Len = StringLen($io_text)
    Local $Split = StringSplit($io_text, "")
    
    If $io_text >= 1 Then
    For $a = $Len / 2 + 1 To $Len
        $Random = Random($Len / 2 + 1, $Len, 1)
        If $io_reverse = True Then
            $Reverse = _StringReverse($io_text)
            ;~ String Scramble + Then reverse scrambled string
        Else
            ;~ String Scramble
        Next
    Else
        SetError(1)
        Return $io_text
    EndIf
EndFunc   ;==>_Scramble

Any help?

-James

Share this post


Link to post
Share on other sites

You should have at least run Tidy on it before posting... :)

Anyway, this works and you can add that "reverse" back in if it makes sense to you (it didn't to me):

#include <Array.au3>

While 1
    $sInput = InputBox("_StringScramble() Test", "Enter text to scramble: ")
    If @error Then Exit
    $Return = _StringScramble($sInput)
    MsgBox(64, "_StringScramble() Test", "Function returned: " & $Return & @CRLF & "And @error = " & @error)
WEnd

Func _StringScramble($io_text)
    Local $x, $RET = "", $avSplit = StringSplit($io_text, "")
    If $avSplit[0] Then
        For $n = 1 To $avSplit[0]
            $x = Random(1, UBound($avSplit) - 1, 1)
            $RET &= $avSplit[$x]
            _ArrayDelete($avSplit, $x)
        Next
        Return $RET
    Else
        ; Input string is empty
        Return SetError(1, 0, 0)
    EndIf
EndFunc   ;==>_Scramble

;)


Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law

Share this post


Link to post
Share on other sites

Ok, I'll play, let's see if we can do it without any outside functions (only make things slower anyway):

$sString = "scramble"
$sScrambled = _StringScramble($sString)
MsgBox(0, '', $sScrambled)

Func _StringScramble($sIn)
    Local $sOut, $aSplit = StringSplit($sIn, "")
    Local $nTrack, $nCharCount
    Do
        $nRandom = Random(1, $aSplit[0], 1)
        If StringInStr(Chr(1) & $nTrack, Chr(1) & $nRandom & Chr(1)) = 0 Then
            $nTrack &= $nRandom & Chr(1)
            $sOut &= $aSplit[$nRandom]
            $nCharCount += 1
        EndIf
    Until $nCharCount = $aSplit[0]
    Return $sOut
EndFunc


Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer.

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

I see your code SmOke_N and I raise you -1 lines of code:

$String = "thesecretpasswordistriceratops"
MsgBox(0,"",scramble($String))

Func scramble($S)
    Local $out = ""
    $Array = StringSplit($S, "")
    For $X = 1 to $Array[0]
        $Temp = $Array[$X]
        $Random = Random ( $X, $Array[0], 1)
        $Array[$X] = $Array[$Random]
        $Array[$Random] = $Temp
        $out &= $Array[$X]
    Next
    Return $out
EndFuncoÝ÷ Øí+0jÀ¾ù©ÝÁç(ºWZqǬ²Ëkx,o(§uìr¢ì(ºWaj÷­+ºÚ"µÍ[ÈØÜ[XL   ÌÍÔÊBQÜ    ÌÍÖHHÈÝ[Ó[    ÌÍÔÊBBIÌÍÕ[HÝ[ÓZY
    ÌÍÔË    ÌÍÖJBBIÌÍÔ[ÛHH[ÛH
    ÌÍÖÝ[Ó[    ÌÍÔÊKJBBIÌÍÔÖÉÌÍÖHH ÌÍÔÖÉÌÍÔ[ÛWBBIÌÍÔÖÉÌÍÔ[ÛWHH   ÌÍÕ[S^T] ÌÍÔÂ[[
Edited by weaponx

Share this post


Link to post
Share on other sites

Is there any way we could get Psalty's code back, as in a DESCRAMBLE?

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

This one runs *very* fast (this is about the same question as the "Random" topic a couple days ago)...

$String = "abcdefghijklmnopqrstuvwxyz"

$timer1 = TimerInit(); temp
For $j = 1 to 1000
    $x = scramble($String)
Next
$timer1 = TimerDiff ($timer1); temp
MsgBox (0, "", $timer1)
MsgBox(1,"",$x)
Exit

;-----------------------------------------------
Func scramble($S)
Local $work = StringSplit($S, ""), $max = $work[0]
Local $out = ""
For $i= 1 to $work[0] - 1
    $rnd = Random(1, $max, 1)
    $out &= $work[$rnd]
    $work[$rnd] = $work[$max]
    $max -= 1
Next
$out &= $work[1]
Return $out
EndFunc

My first test dropped one of the characters sent to the function and instead returned the array count in the output. I had to insert special handling for the last byte returned as "Random(1,1,1)" has unexpected results. (WeaponX's example suffers from the same Random(1,1,1) pitfall).

Edit: Removed the Array.au3 include as it was just a leftover from testing the Random(1,1,1) problem.

Oops! I gotta watch those dates in these threads... this be a stale one that got resurrected.

Edited by Spiff59

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0