So I thought I would build an encryption system that can be used to hide value data from the evil hex-code editors... Things are going ok, but I cant find an efficient way to sort an array without using multiple for() loops. Is there a simple way to randomize array values? I initialy used a for() loop to pull a random value out of the initial array and place it in a buffer array that holds temp values. When the buffer fills it is copied onto the origional array and cleared. The problem with the way I did it is that it created duplicates... Is there an easier, more efficient way to randomize an array? JS please...
Perhaps if you can give an example of what you're trying to accomplish there might be a better way. Simple bit twiddling and separating the displayed from the real value is more than enough to protect against memory editor hacks. What sort of data are you trying to protect that involves expensive tasks such as sorting, randomizing and copying arrays?
Personaly I would use it for saving XML data to the client's computer. It realy isn't too expensive, the randomizing will only be executed at game initialization. I have an array with a length of 94. What I need to do is shuffle the array, without creating duplicates.
Having trouble with this. I have two arrays, array1 and array2. As far as I can tell, this should set array2 = array1, then randomize array2 and leave array1 alone. This is not happening... I'm not sure what is going wrong, the code makes sense to me. :? Code (csharp): function ShuffleArray() // Ends up randomizing array1... { if (doOnce4 == true) { array2 = array1; var temp; for (var i = 0; i < array2.length; i++) { temp = array2[i]; var swapIndex = Random.Range(0,(array2.length - 1)); array2[i] = array2[swapIndex]; array2[swapIndex] = temp; } Debug.Log(array1); doOnce4 = false; } }
That makes array2 be a pointer to array1, so anything that happens to array1 also happens to array2, since they are the same thing and not two separate arrays. --Eric
Code (csharp): var j = 94; for (i = 0; i < j; i++) { var rand:int = Random()*j; shuffled_arr[i] = main_arr.RemoveAt(rand); j--; } Off the top of my head I shuffled cards with this but using splice which is not available in Unity. I think RemoveAt accomplishes the same thing. HTH
Just came across this thread. I was too lazy to use the library so I wrote my own (Unity JavaScript) shuffle routine: Code (csharp): function Shuffle( size : int ) : int[] { var cards : int[] = new int[size]; var r : int; var i : int; var temp : int; for( i = 0; i < size; i++ ){ cards[i] = i; } for( i = 0; i < cards.length; i++ ){ r = Random.Range(0, i); temp = cards[r]; cards[r] = cards[i]; cards[i] = temp; } return cards; } The idea is to use a shuffled array of ints to refer to some other array. I can prove the result is correct by induction: 1) Obviously works for array of one element. 2) Assuming it works for arrays of n elements (i.e. you get an array where each element has a 1/n probability of being in each position) consider an array of n+1 elements: When you get to the nth step the routine is (assumed to be) correct. So the final step has a 1/(n+1) chance of swapping the final element with any other element, so the probability the final element will end up in any position is 1/(n+1) Now consider any element in the array of size n. The probability of it being in a given position m before the final step was 1/n. In the final step it has a n/(n+1) chance of staying put. So its probability of being at position m after the final step is 1/n * n/(n+1) or 1/(n+1). QED and no dynamically resizing elements needed. Yes I wasted way too much time on this, but it could be useful where performance is an issue (e.g. for shuffling big arrays)
Not the most efficient way peformance wise, but you could use the linq OrderBy method: C# code. Code (csharp): System.Random randomGenerator = new System.Random(); array2 = array1.OrderBy(x => randomGenerator.Next(1, 1000)).ToArray(); Which will leave array1 as it was and set array2 to a new shuffled version. If that is what you want. Edit: Didn't realise how old the original post was.
LOL. I recently used that method - just be warned that the random number has to be large compared to the length of the array before it begins to appear random [and even then there is probably some statistical bias].
There is absolutely no way you'll "hide value data from the evil hex-code editors" without actual encryption. Shuffling arrays is not going to do it. The bad guys are way better than the good guys with this stuff.
While I agree, shuffling the data around in memory does knock out the first level of hex hacker. However, since he doesn't seem to keep track of the different order, I don't see how he can use the data now, either... That, or it's just as useful to the 'hackers'.
If I'm searching a file (he mentions hex-code editors, so I'm just assuming) and I know I have 24,500 gold pieces, it doesn't matter where in the file that value is. CMD-F, 24,500, and busted. Forget level one, my dog could do that. But if it's stored as a0293^@*d10134 (pretend that's 24,500 encrypted) then I have a problem.
Guys, I'd modify the array shuffle function if I were you. It is not a true Fisher-Yates shuffle which makes it problematic, especially if it was used for card shuffling. See this wikipedia article to correct it. http://en.wikipedia.org/wiki/Fisher–Yates_shuffle See the part where it says "The modern algorithm" Felt nice so here is the code to replace the Shuffle method. Code (csharp): public static void Shuffle<T>(T[] array) { int count = array.Length; for(int i = count-1; i > 0; --i) { int randIndex = Random.Range(0, i); T temp = array[i]; array[i] = array[randIndex]; array[randIndex] = temp; } }
i have wrapped the improved method into an extension method and made it for list as well as array. note: for many elements the string gets really long and unwieldy. the display method uitilizes the tostring method so this should be overwritten by your objects in order to display meaningfull values. important: the array/list itself is reordered so if you need to keep the original order only call the shuffle method on a copy of your list/array! have fun. Code (csharp): using System.Collections.Generic; using System.Text; public static class ExtensionMethods_Collection { public static void Shuffle<T> ( this List<T> list ) {// shuffles the elements in the list randomly with knuth fischer yates shuffle, source: http://forum.unity3d.com/threads/46234-Shuffling-an-array, http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle, http://forum.unity3d.com/threads/29977-Randomising-shuffling-library int count = list.Count, i, randIndex; for (i = count - 1; i > 0; --i) { randIndex = Random.Range ( 0, i ); // note: shifts random elements to the foward going end so the order is determined in opposite direction, the elements choosen first are the last ones in the resulting list T temp = list[i]; list[i] = list[randIndex]; list[randIndex] = temp; } } public static void Shuffle<T> ( this T[] array ) {// shuffles the elements in the list randomly with knuth fischer yates shuffle, source: http://forum.unity3d.com/threads/46234-Shuffling-an-array, http://en.wikipedia.org/wiki/Fisher%E2%80%93Yates_shuffle, http://forum.unity3d.com/threads/29977-Randomising-shuffling-library int count = array.Length, i, randIndex; for (i = count - 1; i > 0; --i) { randIndex = Random.Range ( 0, i ); T temp = array[i]; array[i] = array[randIndex]; // note: shifts random elements to the foward going end so the order is determined in opposite direction, the elements choosen first are the last ones in the resulting list array[randIndex] = temp; } } public static string ElementsToString<T>(this List<T> list) {// returns the elements of the list as a string (fe for output or debug) StringBuilder result = new StringBuilder(1024); int end = list.Count - 1; result.Append(string.Format("Elements: {0} Content: {{ ", list.Count)); for (int i = 0; i < list.Count; ++i) { result.Append ( list[i].ToString ( ) ); if (i < end) result.Append ( ", " ); } result.Append("}"); return result.ToString(); } public static string ElementsToString<T>(this T[] array ) {// returns the elements of the list as a string (fe for output or debug) StringBuilder result = new StringBuilder ( 1024 ); int end = array.Length - 1; result.Append ( string.Format ( "Elements: {0} Content: {{ ", array.Length ) ); for (int i = 0; i < array.Length; ++i) { result.Append ( array[i].ToString ( ) ); if (i < end) result.Append ( ", " ); } result.Append ( "}" ); return result.ToString ( ); } } usage: Code (csharp): List<int> indices = new List<int>(10) {1,2,3,4,5,6,7,8,9,10}; indices.Shuffle(); Debug.Log(indices.ElementsToString()); float[] values = new float[] {1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f, 10.10f}; values.Shuffle(); Debug.Log(values.ElementsToString());