Iterating over maps in Go

Jun 23, 2023 - 2 min read

Iterating over maps in Go

Iterating over maps in golang

There is some interesting behaviour about how a for-range loop iterates over a map.

func main() { m := map[string]string{ "a": "Alice", "b": "Ben", "c": "Charlie", } for i := 0; i < 3; i++ { fmt.Println("Iteration", i) for k, v := range m { fmt.Println(k, v) } } }

When you build and run this program, the output varies. For example:

Iteration 0 a Alice b Ben c Charlie Iteration 1 a Alice b Ben c Charlie Iteration 2 b Ben c Charlie a Alice

The order of the keys and values are always random. After some research, I have found out that is intentional security feature. If maps always hash items to the exact same values, and you know that a server is storing some user data in a map, you can actually slow down a server with an attack called Hash DoS by sending it specially crafted data where all of the keys hash to the same bucket.

To prevent this problem, the Go team made some changes. They modified the hash algorithm for maps to include a random number thats generated every time a map variable is created. Next, they made the order of a for-range iteration over a map vary a bit each time the map is looped over. These two changes make it harder to implement a Hash DoS attack.

What is the number one lesson you have learned from this article?