{"id":112683,"date":"2026-09-09T07:00:00","date_gmt":"2026-09-09T14:00:00","guid":{"rendered":"https:\/\/devblogs.microsoft.com\/oldnewthing\/?p=112683"},"modified":"2026-09-09T21:54:11","modified_gmt":"2026-09-10T04:54:11","slug":"20260909-00","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/oldnewthing\/20260909-00\/?p=112683","title":{"rendered":"What algorithm did Windows XP use to choose your initial user picture?"},"content":{"rendered":"<p>I noted some time ago that <a title=\"The martial arts logon picture\" href=\"https:\/\/devblogs.microsoft.com\/oldnewthing\/20040401-00\/?p=39933\"> Windows XP chose your initial picture at random<\/a> from among the pictures in the <tt>%ALLUSERSPROFILE%\\<wbr \/>Application Data\\<wbr \/>Microsoft\\<wbr \/>User Account Pictures\\<wbr \/>Default Pictures<\/tt> directory. But it seems people want to know more.<\/p>\n<blockquote class=\"twitter-tweet\">\n<p dir=\"ltr\" lang=\"en\">Has anyone attempted to figure out the RNG for how Windows XP determines what profile picture is used on first account creation?<\/p>\n<p>\u2014 Xeno (@XenoPanther) <a href=\"https:\/\/twitter.com\/XenoPanther\/status\/1999217479923413284\">December 11, 2025<\/a><\/p><\/blockquote>\n<p><script async src=\"https:\/\/platform.twitter.com\/widgets.js\" charset=\"utf-8\"><\/script><\/p>\n<p>The random number generator is our friend <code>RtlRandomEx<\/code>, using the current value of <code>GetTickCount()<\/code> as the initial seed.<\/p>\n<p>The function uses a one-pass random selection algorithm. I can immediately think of two benefits of this decision. First, compared to the na\u00efve two-pass algorithm of counting up all the items, then randomly picking a number from 1 to <var>n<\/var>, and then iterating a second time to find the item at that index, it&#8217;s more efficient because it reduces the amount of calls into the file system, which is where the bottleneck is. Furthermore, the one-pass algorithm avoids complications if the number of files in the directory changes while the code is running.<\/p>\n<p>The one-pass algorithm is a special case of <a href=\"https:\/\/en.wikipedia.org\/wiki\/Reservoir_sampling\"> reservoir sampling<\/a>, where <var>k<\/var> is 1. This special case permits a tailored algorithm that is much simpler.<\/p>\n<pre>selectRandomFromIterator(iterator)\r\n{\r\n    var count = 0;\r\n    var winner = null;\r\n\r\n    while (iterator.moveNext()) {\r\n        ++count;\r\n        if (uniform_random(min: 1, max: count) == count) {\r\n            winner = iterator.current();\r\n        }\r\n    }\r\n\r\n    return winner;\r\n}\r\n<\/pre>\n<p>The way this algorithm works is by observing that in a collection of <var>n<\/var> items, the last item has a 1\/<var>n<\/var> chance of being randomly selected. If it isn&#8217;t selected, then you need to select randomly from the first <var>n<\/var> \u2212 1 items, which you can solve recursively.<\/p>\n<p>Playing the recursion forward, you start with the base case which is that if you have a list of 1 item, then your only choice is to chose that item. Otherwise, if you have a list of <var>n<\/var> items, first choose an item randomly from the first <var>n<\/var> \u2212 1, and then switch to the <var>n<\/var>th item with a 1\/<var>n<\/var> probability.<\/p>\n<p>As a final safety check, the code stops after sampling 100 pictures. This avoids pathological behavior if somebody puts a million files in the <tt>Default Pictures<\/tt> directory.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s random, really.<\/p>\n","protected":false},"author":1069,"featured_media":111744,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[2],"class_list":["post-112683","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oldnewthing","tag-history"],"acf":[],"blog_post_summary":"<p>It&#8217;s random, really.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112683","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/users\/1069"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/comments?post=112683"}],"version-history":[{"count":1,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112683\/revisions"}],"predecessor-version":[{"id":112685,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/posts\/112683\/revisions\/112685"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media\/111744"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/media?parent=112683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/categories?post=112683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/oldnewthing\/wp-json\/wp\/v2\/tags?post=112683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}