Jump to content
Sign in to follow this  
James

Scramble a string

Recommended Posts

James

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
PsaltyDS

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
SmOke_N

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
weaponx

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
glasglow

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
Spiff59

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  

×

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.