shkspr.mobi.atom.xml - sfeed_tests - sfeed tests and RSS and Atom files
(HTM) git clone git://git.codemadness.org/sfeed_tests
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
shkspr.mobi.atom.xml (202619B)
---
1 <?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="https://shkspr.mobi/blog/wp-content/themes/edent-wordpress-theme/atom-style.xsl" type="text/xsl"?><feed
2 xmlns="http://www.w3.org/2005/Atom"
3 xmlns:thr="http://purl.org/syndication/thread/1.0"
4 xml:lang="en-GB"
5 >
6 <title type="text">Terence Eden’s Blog</title>
7 <subtitle type="text">Regular nonsense about tech and its effects 🙃</subtitle>
8
9 <updated>2025-07-09T21:12:31Z</updated>
10
11 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog" />
12 <id>https://shkspr.mobi/blog/feed/atom/</id>
13 <link rel="self" type="application/atom+xml" href="https://shkspr.mobi/blog/feed/atom/" />
14
15 <generator uri="https://wordpress.org/" version="6.8.1">WordPress</generator>
16 <icon>https://shkspr.mobi/blog/wp-content/uploads/2023/07/cropped-avatar-32x32.jpeg</icon>
17 <entry>
18 <author>
19 <name>@edent</name>
20 </author>
21
22 <title type="html"><![CDATA[Gadget Review: Thermal Imaging Camera - Topdon TC004 Mini ★★★⯪☆]]></title>
23 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/" />
24
25 <id>https://shkspr.mobi/blog/?p=61523</id>
26 <updated>2025-07-09T21:12:31Z</updated>
27 <published>2025-07-10T11:34:53Z</published>
28 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="gadget" /><category scheme="https://shkspr.mobi/blog" term="infrared" /><category scheme="https://shkspr.mobi/blog" term="review" /><category scheme="https://shkspr.mobi/blog" term="thermal" />
29 <summary type="html"><![CDATA[I've reviewed several thermal imaging products over the years. They range from tiny USB-C add-ons to professional quality hulking great handhelds. Topdon have sent me a mid-point model to review. It's relatively cheap for a thermal imaging product - only £140 on Amazon. I think the sensor is made by Raytrontek. But is it any good? While it has a bunch of useful features, there's no video …]]></summary>
30
31 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/"><![CDATA[
32 <html><head></head><body><p>I've reviewed <a href="https://shkspr.mobi/blog/tag/thermal/">several thermal imaging products</a> over the years. They range from <a href="https://shkspr.mobi/blog/2023/06/review-infiray-thermal-usb-c-camera-for-android/">tiny USB-C add-ons</a> to professional quality <a href="https://shkspr.mobi/blog/2024/04/gadget-review-kaiweets-kti-w01-thermal-imaging-camera/">hulking great handhelds</a>.</p>
33
34 <p>Topdon have sent me a mid-point model to review. It's relatively cheap for a thermal imaging product - <a href="https://amzn.to/468ipTY">only £140 on Amazon</a>. I <em>think</em> the sensor is made by <a href="https://en.raytrontek.com/product/infrared.htm">Raytrontek</a>. But is it any good?</p>
35
36 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/71IGxD6iDyL._SL750_.jpg" alt="Thermal Imaging Camera." width="600" height="750" class="aligncenter size-full wp-image-61841">
37
38 <p>While it has a bunch of useful features, there's no video recording and it doesn't work with Linux. Other than that, it's fine.</p>
39
40 <h2 id="the-good-points"><a href="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/#the-good-points" class="heading-link">The Good Points</a></h2>
41
42 <p>It seems broadly accurate. Point it at a bunch of things and you can see their temperature. Here's my beautiful face:</p>
43
44 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/IR20250623073108-rotated.jpeg" alt="Thermal selfie. I have a very cold nose." width="240" height="320" class="aligncenter size-full wp-image-61849">
45
46 <p>That's the actual size of the file. Their marketing bumph says:</p>
47
48 <blockquote><p>TISR (Thermal Image Super Resolution) uses AI algorithms to add simulated pixels between existing ones, enhancing low-resolution thermal images into clearer, high-resolution visuals.</p></blockquote>
49
50 <p>Let's be honest, there's no AI in a device this cheap. There are various complex rules about Infrared cameras and their resolution. These images are fairly low quality - but more than good enough to help you spot a leak or work out if something is too hot.</p>
51
52 <p>Quick start up is great. It is ready to go a few seconds after pushing the power button.</p>
53
54 <p>The trigger grip is comfortable and responsive - it makes the whole device very "point-and-shoot".</p>
55
56 <p>There's a standard tripod screw fitting at the bottom.</p>
57
58 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/tripod.jpg" alt="A screw fitting and lanyard strap." width="1024" height="771" class="aligncenter size-full wp-image-61843">
59
60 <p>The camera is at a slight angle from the grip, so you'll need a tripod with a tiltable mount. You also get an lanyard in the box, which is easily secured to the device.</p>
61
62 <p>There's a file-browser built in - which also lets you delete photos.</p>
63
64 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/File-Browser.webp" alt="Photo of a "Delete this pic" screen." width="600" height="450" class="aligncenter size-full wp-image-61844">
65
66 <p>USB-C for charging and data transfer. Same as all your other gadgets, I hope!</p>
67
68 <h2 id="but"><a href="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/#but" class="heading-link">But…</a></h2>
69
70 <p>Resolution is low. That's normal for these sorts of cameras, but because the output is only 240x320 it means the on-screen text is cramped and looks pretty poor.</p>
71
72 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/IR20250622072705-rotated.jpeg" alt="Camera with a thermal view. It shows how hot something is, with maximum and minimum temperatures." width="240" height="320" class="aligncenter size-full wp-image-61848">
73
74 <p>The interface is basic. It doesn't look brilliant, but it is usable.</p>
75
76 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/Menu.webp" alt="List of menu items." width="600" height="449" class="aligncenter size-full wp-image-61846">
77
78 <p>Setting the time, for example, is a bit of a pain:</p>
79
80 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/date-time-settings.webp" alt="Settings screen with a manual up and down for every setting." width="600" height="450" class="aligncenter size-full wp-image-61845">
81
82 <p>Once you've gone in to set the time and other basic settings, you'll probably never go back to it.</p>
83
84 <p>Storage space is low - only 480MB. To be fair, images are under 100KB, so you could store several thousand before you hit a problem.</p>
85
86 <p>There's no video recording. That's a bit of an arse if you want to see how something heats over time.</p>
87
88 <p>You can't extract temperature information from the images. There's no EXIF, no standard metadata, just whatever is printed over the photo. Again, good enough for a quick check but, given the small viewable size of the images, it would have been nice to print the information separately. You can remove some of the on-screen elements from the image. Here's my <a href="https://shkspr.mobi/blog/2025/03/review-wifi-connected-air-conditioner/">air-conditioning unit</a>:</p>
89
90 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/IR20250702154023-rotated.jpeg" alt="A thermal image. It shows the temperature at the centre of the image." width="240" height="320" class="aligncenter size-full wp-image-61850">
91
92 <p>The rubber flap protecting the charging port makes it difficult to insert the cable.</p>
93
94 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/usb-c.jpg" alt="A USB-C cable with a cover flap pressed tightly against it." width="1024" height="771" class="aligncenter size-full wp-image-61842">
95
96 <p>Because the port is on the top of the device, it's sensible to protect it from debris, but it is a bit fiddly to use.</p>
97
98 <h2 id="linux-information"><a href="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/#linux-information" class="heading-link">Linux Information</a></h2>
99
100 <p>This shows up as <code>3474:0020 Raysentek Co.,Ltd Raysentek MTP</code>. In theory, it should just show up as a device in your file explorer. But it doesn't work.</p>
101
102 <p>I couldn't detect anything with <code>mtp-device</code> - it didn't show up. dmesg showed the dreaded <code>device not accepting address 53, error -71</code> which, I think, indicates a power problem.</p>
103
104 <p><code>lsusb -v</code> shows it claims to support <a href="https://en.wikipedia.org/wiki/Picture_Transfer_Protocol">Picture Transfer Protocol</a>.</p>
105
106 <p>I reset the device, formatted its memory, used different cables and ports, restarted everything, I even tried it on my Android phone. Nothing.</p>
107
108 <p>Which rather puts a damp squib on things. If you can't get the images off the device, you're stuck peering at them on a tiny screen with no way to share them with others.</p>
109
110 <p>It <em>will</em> work with Windows. I tried it in VirtualBox and it showed up - albeit with the name "Cobra".</p>
111
112 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/Cobra.webp" alt="Windows setting screen for Cobra by Raysentek." width="581" height="497" class="aligncenter size-full wp-image-61847">
113
114 <h2 id="verdict"><a href="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/#verdict" class="heading-link">Verdict</a></h2>
115
116 <p>Fora quick and dirty inspection, this is a perfectly fine little device. Point it at a thing and see how hot it is. Squeeze the trigger and capture the image for later viewing.</p>
117
118 <p>The tripod attachment is handy and there are enough settings hidden away for you to set it up for your own personal needs.</p>
119
120 <p>The buttons feel a bit crap and flap gets in the way of the USB-C charging port.</p>
121
122 <p>It doesn't work with Linux or Android - I wasn't able to test it on a Mac - so make sure you have Windows available for getting the images off it.</p>
123
124 <p>This is one of the cheapest stand-alone thermal cameras you can buy. Necessarily, there are compromises involved with things at this price-point. The camera works (albeit not with Linux) and is a great way to get started with Infrared photography and monitoring.</p>
125 </body></html>]]></content>
126
127 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/#comments" thr:count="1" />
128 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/gadget-review-thermal-imaging-camera-topdon-tc004-mini/feed/atom/" thr:count="1" />
129 <thr:total>1</thr:total>
130 </entry>
131 <entry>
132 <author>
133 <name>@edent</name>
134 </author>
135
136 <title type="html"><![CDATA[Book Review: The World After Amazon - Stories from Amazon Workers by Xenia Benivolski ★★★☆☆]]></title>
137 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-the-world-after-amazon-stories-from-amazon-workers-by-xenia-benivolski/" />
138
139 <id>https://shkspr.mobi/blog/?p=61798</id>
140 <updated>2025-07-07T15:55:01Z</updated>
141 <published>2025-07-09T11:34:09Z</published>
142 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Amazon" /><category scheme="https://shkspr.mobi/blog" term="Book Review" />
143 <summary type="html"><![CDATA[This is a brilliant idea for a short story collection. Gather a group of non-writers, all of whom have experienced the dystopia of working for Amazon, and support them to write speculative science fiction. Given how futuristic Amazon is, perhaps they have a unique insight into what its future holds. Or, as the rather academic intro puts it: The Worker as Futurist project asks another question: …]]></summary>
144
145 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/book-review-the-world-after-amazon-stories-from-amazon-workers-by-xenia-benivolski/"><![CDATA[
146 <html><head></head><body><p>This is a brilliant idea for a short story collection. Gather a group of non-writers, all of whom have experienced the dystopia of working for Amazon, and support them to write speculative science fiction. Given how futuristic Amazon is, perhaps they have a unique insight into what its future holds. Or, as the rather academic intro puts it:</p>
147
148 <blockquote><p>The Worker as Futurist project asks another question: if SF is so important to the operations of capitalism in the twenty-first century, does it also have a radical potential that might lend itself to the struggles of workers and other oppressed people within, against and beyond that system? (see Jameson 2005; Roke 2020)</p></blockquote>
149
150 <p>I'll be honest, it feels a <em>little</em> patronising. The project articulates its theory of change (which only <em>slightly</em> puts me in mind of <a href="https://charles-harris.co.uk/2019/11/does-satire-work/">Peter Cook's famous quote</a>) - hoping that radical fiction might move mountains:</p>
151
152 <blockquote><p>We at the Worker as Futurist project believe that workers can fruitfully understand, theorize, and plot forms of resistance to capitalism through creative expression, especially through the process of writing, particularly within the genre of SF. If, as we have argued, SF is now active in important ways at the very heart of capitalism, maybe that genre is also somehow the system’s achilles’ heel?</p></blockquote>
153
154 <p>Still, it makes for a fascinating introduction to a somewhat uneven set of stories. There is some delightfully weird fiction - I especially enjoyed the idea of the University of the Phoenix using AI to write curses on corporations. In amongst that there's some fairly standard stories of worker exploitation, a few overwritten pieces, and one or two which would make great full length books.</p>
155
156 <p>The afterword is very clear about the reason for this book existing:</p>
157
158 <blockquote><p>To me, it never mattered whether or not the stories written by the workers in this project would be considered “good” by the well-read literary elite. To me, it only mattered that those who took up the challenge wrote. And by writing, and by speaking their truths, they exploded the paradigm that would render their subjectivity nonexistent.</p></blockquote>
159
160 <p>And I heartily agree with that. I'd rather read a new writer explore the problem-space rather than yet-another trilogy about romance magicians.</p>
161
162 <p>The book is free to download or, if you think the master's tools can dismantle the master's house, you can purchase a copy on Amazon.</p>
163 </body></html>]]></content>
164
165 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-the-world-after-amazon-stories-from-amazon-workers-by-xenia-benivolski/#comments" thr:count="0" />
166 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/book-review-the-world-after-amazon-stories-from-amazon-workers-by-xenia-benivolski/feed/atom/" thr:count="0" />
167 <thr:total>0</thr:total>
168 </entry>
169 <entry>
170 <author>
171 <name>@edent</name>
172 </author>
173
174 <title type="html"><![CDATA[Book Review: Problems Have No Sex - Caroline Haslett (1949)]]></title>
175 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-problems-have-no-sex-caroline-haslett-1949/" />
176
177 <id>https://shkspr.mobi/blog/?p=58424</id>
178 <updated>2025-07-06T21:40:44Z</updated>
179 <published>2025-07-08T11:34:34Z</published>
180 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Book Review" /><category scheme="https://shkspr.mobi/blog" term="feminism" />
181 <summary type="html"><![CDATA[This is the best book on practical feminism that I've read. Because it is long out of print, I had to get the British Library to pull this book out of the archives for me. I'm fascinated by the evolution of feminist discourse in 20th Century UK. I read Myself When Young (1938) which is a series of mini-autobiographies of prominent women. One of them was Dame Caroline Haslett - an electrical…]]></summary>
182
183 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/book-review-problems-have-no-sex-caroline-haslett-1949/"><![CDATA[
184 <html><head></head><body><p>This is the best book on <em>practical</em> feminism that I've read. Because it is long out of print, I had to get the British Library to pull this book out of the archives for me.</p>
185
186 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/Book-Cover.webp" alt="A blue book cover with a spine that reads Problems Have No Sex by Caroline Haslett.">
187
188 <p>I'm fascinated by the evolution of feminist discourse in 20th Century UK. I read <a href="https://shkspr.mobi/blog/2024/09/book-review-myself-when-young-1938/">Myself When Young</a> (1938) which is a series of mini-autobiographies of prominent women. One of them was Dame Caroline Haslett - an electrical engineer <a href="https://shkspr.mobi/blog/2024/05/book-review-the-doors-of-opportunity/">who led a long and fascinating life</a>. One of her crowning achievements was advocating the use electricity to relieve household drudgery. Technology as a tool of feminist liberation.</p>
189
190 <p>As part of her battle for equality, she wrote a book called Problems Have No Sex. Sadly, there are no 2nd hand copies for sale, no scans, and very little written about it. There's <a href="https://eresources.nlb.gov.sg/newspapers/digitised/article/freepress19490623-1.2.33">one contemporary review</a> and that's about it.</p>
191
192 <p>So I made a request to the British Library and, a few days later, sat down in their reading room with the dusty tome.</p>
193
194 <p>All books writing from 2020 will be in the shadow of Covid19. This book, published in 1949, is written in the shadow of the atomic bomb. It starts with the terrifying realisation that a woman has the same physical capability as a man when it comes to pressing the button which drops a bomb. While men and women may have different levels of strength, technology is the great leveller.</p>
195
196 <p>The influx of women into traditionally male environments allowed for a <em>practical</em> demonstration of feminism. It's all very well theorising that women are as capable as men but, as every engineer knows, you need to be able to prove it.</p>
197
198 <blockquote><p>Sir Robert Watson Watt, the discoverer of radiolocation, speaking of the way in which women without previous experience in science had taken up this vital work, said: "The question I asked myself was, if these girls could reach such heights in the comparatively short period during which they had contact with physics, what would they have done with a decent education in technical, scientific and engineering studies?"</p>
199
200 <p>It is evident, however, that in addition to the revision of the school syllabus there will need to be a change in the attitude held up to boys as the correct one to adopt towards girls and their capacities.</p>
201
202 <p>There are signs that this is occurring spontaneously. A boy reproached by his father for being beaten in class by a "mere" girl, remarked thoughtfully, "You know, father, I don't think girls are so very mere nowadays."</p></blockquote>
203
204 <p>The book spends a decent amount of space on pregnancy and its effects on women in the workplace. This was written pre-pill but in an era with <a href="https://shkspr.mobi/blog/2025/05/book-review-protective-practices-a-history-of-the-london-rubber-company-and-the-condom-business-by-jessica-borge/">relatively easy access to contraception</a>. Haslett talks frankly about the realities of menstruation - which surprised me somewhat - and whether reproduction is compatible with employment (spoiler alert; yes).</p>
205
206 <p>In amongst some slightly tedious legal matters of the day are some forthright pleas for cheaper electricity so that women can be released from manual labour at home. There's also the <em>realities</em> of what it means to place people in a radically upgraded situation. You can't expect anyone to suddenly know how to operate:</p>
207
208 <blockquote><p>Women must see that the vast amount of talk which there has been about kitchen planning is translated into action and that properly planned kitchens are included in all the new houses built. In addition to the importance of good design and lay-out and the provision of proper equipment as a <i lang="la">sine qua non</i>, there is much scope for education of the housewife in planning her housework along labour-saving lines; and in the teaching of the principles of motion study in the home so that the maximum benefit can be gained from the use of the equipment provided.</p></blockquote>
209
210 <p>Haslett is undoubtedly technocratic but, above all, she is realistic. She has an excellent and provable <a href="https://shkspr.mobi/blog/2025/01/book-review-rules-for-radicals-a-pragmatic-primer-for-realistic-radicals-by-saul-alinsky/">theory of change</a>. This isn't a rant nor a call to arms. She is calm, methodical and ruthlessly determined to set out the problems and solutions.</p>
211
212 <blockquote><p>The sense of having prove herself equal to a male colleague sometimes makes a woman self-assertive and over-aggressive; while the fear of loss of personal prestige or of social or economic insecurity arising from admitting women to full equality makes some men unco-operative and unjust towards women working outside the home. As Miss Hilda Martindale remarks in her book From One Generation to Another: "I found that opposition to working with women on equal terms seldom came from the man who was first class at his work; it was the man who was not sure of himself who objected."</p>
213
214 <p>In manual as opposed to professional types of work the fear "If I show her how to do my job, the boss may sack me because he need not pay her so much" is a cogent argument for equal pay.</p></blockquote>
215
216 <p>Equal pay is a battle which is still being fought, unfortunately.</p>
217
218 <p>There is also just a <em>hint</em> of radical politics lurking under the sometimes-bland prose. Should tariffs be imposed? Are trade-barriers a good way to promote equality? Should women be more self-assured about entering politics and agitating for change?</p>
219
220 <p>There's also an undercurrent of rage directed at the women who helped bring about the war.</p>
221
222 <blockquote><p>The rise of Nazi Germany and Fascist Italy was made possible by the individual man delegating his personal responsibility to a Fuehrer or a Duce —and by the individual woman abandoning her responsibility towards mankind in general and devoting herself entirely and unquestioningly to child-bearing, and the routine work of the home. This wholesale shirking of individual responsibility was the one thing which made possible the creation of the Nazi system with its concomitants of the concentration camp, the mass crematorium and the battlefield.</p></blockquote>
223
224 <p>Prophetically, she notes that the next 20 years should be one of the most interesting periods of history to live in. I'd certainly say that the change from 1949 to 1969 was just that!</p>
225
226 <p>Unlike some other books, this is realistic about the timeframes involved in wholesale cultural change. She sets out how many years of vigilance will be needed to ensure that schools are equipping their female students with the knowledge, ambition, and advice to help them survive in the future. Similar Government, which is lambasted as being far too slow, is shown as needing to embrace radical change. It should be remembered that Churchill, only recently deposed as Prime Minister, was an ardent anti-feminist. He <a href="https://archives.chu.cam.ac.uk/collections/research-guides/womens-suffrage-research-guide/#church">repeatedly stymied the attempts of women to gain the vote</a> - an attitude which is often conspicuously overlooked in the 21st century. I imagine that left a bitter taste in the mouths of Haslett and her contemporaries.</p>
227
228 <p>Women's organisations are also the recipient of Haslett's unsentimental gaze. They need to step up their game, raise more money, and set realistic goals. Similarly, women MPs must make sure not to concern themselves <em>only</em> with women's issues. And, for that matter, women have to stop lollygagging and start using their vote. Finally, she sets out ways in which society has to guard against a backlash to feminism.</p>
229
230 <p>There is a whole discussion about the structural ephemera which causes resentment. The slow build up of unjust laws and customs hurts everyone.</p>
231
232 <p>Now, obviously, people are the product of their time. The book is strongly focused on the UK and isn't <em>too</em> dodgy on race. There's an occasional mention of the USA and a brief sceptical look at the USSR's claims of feminist equality. She does go a little further. Here's a sample from the chapter "Citizens of the World":</p>
233
234 <blockquote><p>Although in Great Britain and the United States women have achieved not only a considerable measure of “equality” but also a very considerable store of experience in the political, economic, and scientific fields: yet there are still countries where women have no rights at all.</p>
235
236 <p>Just as different races have reached different stages of civilization so that the primitive tribes of New Guinea co-exist with the highly civilized European races; so different races have reached different stages in their attitude towards women. This latter difference bears no obvious relation to their general level of technical or cultural development. There may in fact be a much greater equality of contribution towards the common life (which is the fundamental basis of equality between the sexes) among some primitive races than among some very highly civilized ones.</p>
237
238 <p>While these differences and inequalities persist, trained women will have a continuing obligation towards those who are striving to become politically articulate or who, by reason of the inferior status conferred upon them by their own community, are in danger of exploitation.</p>
239
240 <p>It is necessary also to have a realistic appreciation of the differences that may underlie a superficial equality.</p>
241
242 <p>The women of Japan were enfranchised almost simultaneously with the women of France, but the women of Switzerland still remain without voting rights.</p>
243
244 <p>Yet to deduce from the equality of political rights conferred on the women of France and Japan alike that the women of these two countries possessed indeed comparable opportunities and status would be fantastic.</p>
245
246 <p>The traditional Japanese woman, educated from birth to consider herself of no account and completely subservient to the men of her family, will need many years of education and opportunity before she is capable of political responsibility. To expect her to derive maximum advantage at the present time from her enfranchisement would be as logical as to suppose that a woman from the Middle Ages, could she be miraculously transported through time and placed in a modern labour-saving house, could be expected to know just what would happen if she turned certain knobs and switches; and to understand the part that electrical power plays in the modern community.</p>
247
248 <p>The adoption of Western democratic machinery by nations of other cultural traditions implies that we have a continuing obligation to these peoples until education has made plain the fundamental principles underlying our way of life.</p>
249
250 <p>Some of the Eastern nations are tackling their problems themselves with considerable energy. China with its great drive to stamp out illiteracy has done much to remove the burden of ignorance which has held that great country in economic thralldom for so long. It may well be that the imitative genius of Japan, which derived so much from the influence of China upon its art and culture in the past, will draw from Chinese sources more readily than from the West a new concept of the status of women in human society. The work of Mme. Chiang Kai Shek and her sisters may be the keystone of women’s emancipation in the East.</p>
251
252 <p>In this age we are setting up the pattern for life of succeeding generations. Women must see that the mistakes which our own nations made in their development are not through ignorance or greed perpetuated in other lands.</p></blockquote>
253
254 <p>She is curiously circumspect on the issue of disability. Post-war, I imagine many people wanted to ignore the horrors which rent bodies asunder. The only mention is:</p>
255
256 <blockquote><p>Yet even in Britain a very great number of people lead unnecessarily cramped and limited lives, and the social conscience of the country is awakening to their needs. It is being recognized, for example, that it is not sufficient to give disabled people a weekly pension to keep them from actual hunger or to provide institutions in which they can be housed. The disabled person has as much right to a full and useful life, within the limits of his or her disability, as anyone else.</p></blockquote>
257
258 <p>Ultimately, this book is about what we owe to each other. Women won the war, then they rightly demanded to win the benefits of peace.</p>
259
260 <p>"Problems Have No Sex" is <em>far</em> better than many other feminist books I've read simply because of its lack of academic pretentiousness. Other than the occasional Latin phrase, the book is written in plain English - designed to be read and understood as widely as possible. As an engineer, Dame Haslett has an engineer's approach to problem solving - identify the issue, determine the cause, suggest solutions, investigate what works and what doesn't, repeat until fixed.</p>
261
262 <p>Every feminist should read this book. I'm annoyed that it has never been reprinted and that there's no eBook available. Under UK copyright, it should enter the public domain in 2028. Hopefully a scan will be released which will allow everyone to read this important work.</p>
263 </body></html>]]></content>
264
265 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-problems-have-no-sex-caroline-haslett-1949/#comments" thr:count="1" />
266 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/book-review-problems-have-no-sex-caroline-haslett-1949/feed/atom/" thr:count="1" />
267 <thr:total>1</thr:total>
268 </entry>
269 <entry>
270 <author>
271 <name>@edent</name>
272 </author>
273
274 <title type="html"><![CDATA[Grinding down open source maintainers with AI]]></title>
275 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/" />
276
277 <id>https://shkspr.mobi/blog/?p=61265</id>
278 <updated>2025-07-02T16:34:08Z</updated>
279 <published>2025-07-07T11:34:09Z</published>
280 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="AI" /><category scheme="https://shkspr.mobi/blog" term="git" /><category scheme="https://shkspr.mobi/blog" term="LLM" /><category scheme="https://shkspr.mobi/blog" term="spam" />
281 <summary type="html"><![CDATA[Early one morning I received an email notification about a bug report to one of my open source projects. I like to be helpful and I want people who use my stuff to have a good time, so I gave it my attention. Here's what it said: 😱 I Can't Use On This Day 😭 Seriously, What’s Going On?! 🔍 I’ve been trying to use the On This Day feature, but it’s just not working for me! 😩 Every time I input my d…]]></summary>
282
283 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/"><![CDATA[
284 <html><head></head><body><p>Early one morning I received an email notification about a bug report to one of my open source projects. I like to be helpful and I want people who use my stuff to have a good time, so I gave it my attention. Here's what it said:</p>
285
286 <blockquote>
287 <h2 id="%f0%9f%98%b1-i-cant-use-on-this-day-%f0%9f%98%ad"><a href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/#%f0%9f%98%b1-i-cant-use-on-this-day-%f0%9f%98%ad" class="heading-link"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f631.png" alt="😱" class="wp-smiley" style="height: 1em; max-height: 1em;" /> I Can't Use On This Day <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" /></a></h2>
288 Seriously, What’s Going On?! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
289 I’ve been trying to use the On This Day feature, but it’s just not working for me! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f629.png" alt="😩" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
290 Every time I input my details, it says I have no posts for today, even though I know I’ve posted stuff! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f9d0.png" alt="🧐" class="wp-smiley" style="height: 1em; max-height: 1em;" />
291
292 <h3 id="heres-my-setup-%e2%9a%99%ef%b8%8f"><a href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/#heres-my-setup-%e2%9a%99%ef%b8%8f" class="heading-link">Here’s My Setup: <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/2699.png" alt="⚙" class="wp-smiley" style="height: 1em; max-height: 1em;" /></a></h3>
293
294 <ul>
295 <li>Python 3.x <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f40d.png" alt="🐍" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
296 <li>Access token fully generated (I triple-checked!) <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f511.png" alt="🔑" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
297 <li>Attempted on multiple instances but still nothing! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f629.png" alt="😩" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f629.png" alt="😩" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>
298 </ul>
299
300 <h3 id="could-it-be-a-bug-%f0%9f%a4%94"><a href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/#could-it-be-a-bug-%f0%9f%a4%94" class="heading-link">Could It Be a Bug? <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /></a></h3>
301
302 I’m really starting to doubt my posting history! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f633.png" alt="😳" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
303 Is it supposed to show only specific types of posts?<br>
304 I’ve made some pretty epic posts before! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f4a5.png" alt="💥" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f4ac.png" alt="💬" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
305
306 <h3 id="documentation-confusion-%f0%9f%93%9a"><a href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/#documentation-confusion-%f0%9f%93%9a" class="heading-link">Documentation Confusion <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f4da.png" alt="📚" class="wp-smiley" style="height: 1em; max-height: 1em;" /></a></h3>
307
308 The README says to register for an access token but doesn’t clarify if it factors into this feature! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f914.png" alt="🤔" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/2753.png" alt="❓" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
309 Did I miss something REALLY important?!<br>
310 Help me figure this out, please!!! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f631.png" alt="😱" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
311
312 <h3 id="feature-suggestion-%f0%9f%92%ad"><a href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/#feature-suggestion-%f0%9f%92%ad" class="heading-link">Feature Suggestion <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f4ad.png" alt="💭" class="wp-smiley" style="height: 1em; max-height: 1em;" /></a></h3>
313
314 If this is broken, can we at least have a debug mode to log what’s happening! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f62c.png" alt="😬" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
315 I need to know if it’s truly my fault or the code’s! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f6e0.png" alt="🛠" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
316 Thanks for looking into this TRAGIC situation!!! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f62d.png" alt="😭" class="wp-smiley" style="height: 1em; max-height: 1em;" /><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f494.png" alt="💔" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
317 <br>
318 P.S. My friends ARE posting on this day and their instances work!! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f624.png" alt="😤" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
319 I feel so left out!! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f61f.png" alt="😟" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br>
320 Let’s get this sorted ASAP! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/26a1.png" alt="⚡" class="wp-smiley" style="height: 1em; max-height: 1em;" />
321 </blockquote>
322
323 <p>OK, that's a <em>lot</em> of Emoji - too much even for me! But if one of my users needs help, I'm there for them! As the feature works for me, I decided I'd ask for the output of the app. Maybe there'd be a clue in the minimal debugging output it had.</p>
324
325 <p>I clicked on the link to the Codeberg repository and was hit be a 404! What? I clicked on the link to the user "simpleseaport2" but that was also broken.</p>
326
327 <p>"Seriously, What’s Going On?! <img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f50d.png" alt="🔍" class="wp-smiley" style="height: 1em; max-height: 1em;" />"</p>
328
329 <p>It looks like Codeberg has been hit by a wave of spam bug reports. I read through the bug report again, slightly more awake, and saw just how content free it was. Yes, it is superficially well structured, the Emoji are a bit over-the-top but not the worst I've seen, and the emotional manipulation is quite insidious.</p>
330
331 <p>A few weeks later, I got a bug report to a different repo. This one was also deleted before I could reply to it, see if you can spot that it is AI generated:</p>
332
333 <blockquote><p>I've been trying to use the Threads tool to visualize some conversations but I'm running into a serious problem, and it's really frustrating!
334 </p><p>When I input the URL for a post with a substantial number of replies, the script seems to hang indefinitely. I've waited more than 15 minutes on a couple of occasions, and nothing seems to happen. This is not what I expected, especially since the README mentions large conversations may take a long time, but doesn’t specify any limits or give guidance on what users should do if it doesn’t respond at all!
335 </p><p>It's unclear what's actually happening here. Is the script failing silently? Is it the API timing out? Why isn’t there any sort of progress notification built into the tool? It feels like a complete dead end.
336 </p><p>Can you please add some kind of error handling or logging feature to the Threads script? It would be helpful if it could at least inform the user when a timeout occurs or if the API response is simply taking too long. Additionally, could you clarify the maximum number of replies that can be handled? It’s really inconvenient to have no idea if the script is still processing or if it’s just broken.
337 </p><p>Thanks for addressing this. I hope to see improvements soon.</p></blockquote>
338
339 <ul>
340 <li>The emotional manipulation starts in the first line - telling me how frustrated the user is.</li>
341 <li>It turns the blame on me for providing poor guidance.</li>
342 <li>Then the criticism of the tool.</li>
343 <li>Next, a request that I do work.</li>
344 <li>Finally some more emotional baggage for me to carry.</li>
345 </ul>
346
347 <p>I'm not alone in getting these - <a href="https://merveilles.town/@raboof/114589918314200123">other people have also received similar spam</a></p>
348
349 <p>To be fair to Codeberg, they are under attack and are trying to stop these specious complaints reaching maintainers.</p>
350
351 <blockquote class="mastodon-embed" data-embed-url="https://social.anoxinon.de/@Codeberg/114592518436361178/embed" style="background: #FCF8FF; border-radius: 8px; border: 1px solid #C9C4DA; margin: 0; max-width: 540px; min-width: 270px; overflow: hidden; padding: 0;"> <a href="https://social.anoxinon.de/@Codeberg/114592518436361178" target="_blank" style="align-items: center; color: #1C1A25; display: flex; flex-direction: column; font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', Roboto, sans-serif; font-size: 14px; justify-content: center; letter-spacing: 0.25px; line-height: 20px; padding: 24px; text-decoration: none;"> <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="32" height="32" viewBox="0 0 79 75"><path d="M74.7135 16.6043C73.6199 8.54587 66.5351 2.19527 58.1366 0.964691C56.7196 0.756754 51.351 0 38.9148 0H38.822C26.3824 0 23.7135 0.756754 22.2966 0.964691C14.1319 2.16118 6.67571 7.86752 4.86669 16.0214C3.99657 20.0369 3.90371 24.4888 4.06535 28.5726C4.29578 34.4289 4.34049 40.275 4.877 46.1075C5.24791 49.9817 5.89495 53.8251 6.81328 57.6088C8.53288 64.5968 15.4938 70.4122 22.3138 72.7848C29.6155 75.259 37.468 75.6697 44.9919 73.971C45.8196 73.7801 46.6381 73.5586 47.4475 73.3063C49.2737 72.7302 51.4164 72.086 52.9915 70.9542C53.0131 70.9384 53.0308 70.9178 53.0433 70.8942C53.0558 70.8706 53.0628 70.8445 53.0637 70.8179V65.1661C53.0634 65.1412 53.0574 65.1167 53.0462 65.0944C53.035 65.0721 53.0189 65.0525 52.9992 65.0371C52.9794 65.0218 52.9564 65.011 52.9318 65.0056C52.9073 65.0002 52.8819 65.0003 52.8574 65.0059C48.0369 66.1472 43.0971 66.7193 38.141 66.7103C29.6118 66.7103 27.3178 62.6981 26.6609 61.0278C26.1329 59.5842 25.7976 58.0784 25.6636 56.5486C25.6622 56.5229 25.667 56.4973 25.6775 56.4738C25.688 56.4502 25.7039 56.4295 25.724 56.4132C25.7441 56.397 25.7678 56.3856 25.7931 56.3801C25.8185 56.3746 25.8448 56.3751 25.8699 56.3816C30.6101 57.5151 35.4693 58.0873 40.3455 58.086C41.5183 58.086 42.6876 58.086 43.8604 58.0553C48.7647 57.919 53.9339 57.6701 58.7591 56.7361C58.8794 56.7123 58.9998 56.6918 59.103 56.6611C66.7139 55.2124 73.9569 50.665 74.6929 39.1501C74.7204 38.6967 74.7892 34.4016 74.7892 33.9312C74.7926 32.3325 75.3085 22.5901 74.7135 16.6043ZM62.9996 45.3371H54.9966V25.9069C54.9966 21.8163 53.277 19.7302 49.7793 19.7302C45.9343 19.7302 44.0083 22.1981 44.0083 27.0727V37.7082H36.0534V27.0727C36.0534 22.1981 34.124 19.7302 30.279 19.7302C26.8019 19.7302 25.0651 21.8163 25.0617 25.9069V45.3371H17.0656V25.3172C17.0656 21.2266 18.1191 17.9769 20.2262 15.568C22.3998 13.1648 25.2509 11.9308 28.7898 11.9308C32.8859 11.9308 35.9812 13.492 38.0447 16.6111L40.036 19.9245L42.0308 16.6111C44.0943 13.492 47.1896 11.9308 51.2788 11.9308C54.8143 11.9308 57.6654 13.1648 59.8459 15.568C61.9529 17.9746 63.0065 21.2243 63.0065 25.3172L62.9996 45.3371Z" fill="currentColor"></path></svg> <div style="color: #787588; margin-top: 16px;">Post by @Codeberg@social.anoxinon.de</div> <div style="font-weight: 500;">View on Mastodon</div> </a> </blockquote>
352
353 <script data-allowed-prefixes="https://social.anoxinon.de/" async="" src="https://social.anoxinon.de/embed.js"></script>
354
355 <p>But, still, search the socials and you'll find a stream of frustrated developers.</p>
356
357 <blockquote class="bluesky-embed" data-bluesky-uri="at://did:plc:i7qrqashiejmsuo4hbvovw6l/app.bsky.feed.post/3lnkpto5rpdd2" data-bluesky-cid="bafyreigm2vqlybmy5dhawigjqzwhz2p2w3o4gatpykxkurwrzzmtbfif6a" data-bluesky-embed-color-mode="system"><p lang="en">Woke this morning to my first ever AI generated spam issue on a repo. Got it via email. When I went to check it out at Codeberg, it had already been moderated. Wonder how many others were affected.
358
359 I immediately knew it was AI spam due to the overuse of emojis…<img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f389.png" alt="🎉" class="wp-smiley" style="height: 1em; max-height: 1em;" /><br><br><a href="https://bsky.app/profile/did:plc:i7qrqashiejmsuo4hbvovw6l/post/3lnkpto5rpdd2?ref_src=embed">[image or embed]</a></p>— Jeff Sikes (<a href="https://bsky.app/profile/did:plc:i7qrqashiejmsuo4hbvovw6l?ref_src=embed">@bsky.box464.social</a>) <a href="https://bsky.app/profile/did:plc:i7qrqashiejmsuo4hbvovw6l/post/3lnkpto5rpdd2?ref_src=embed">24 April 2025 at 15:07</a></blockquote>
360
361 <script async="" src="https://embed.bsky.app/static/embed.js" charset="utf-8"></script>
362
363 <h2 id="whats-going-on%e2%81%89%ef%b8%8f"><a href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/#whats-going-on%e2%81%89%ef%b8%8f" class="heading-link">What's Going On<img src="https://s.w.org/images/core/emoji/15.1.0/72x72/2049.png" alt="⁉" class="wp-smiley" style="height: 1em; max-height: 1em;" /></a></h2>
364
365 <p>I can only think of a few possibilities - none of them particularly positive.</p>
366
367 <ul>
368 <li>Attacking the viability of CodeBerg - make users abandon it for a different platform.</li>
369 <li>Attacking the attention of developers - make them unwilling to give attention where it is actually needed.</li>
370 <li>Attacking the integrity of users - make them less likely to receive help because they are mistaken for AI.</li>
371 <li>Maybe it is just a bored kid or an unethical researcher. Trying to find the limits of what a maintainer will recognise as spam?</li>
372 </ul>
373
374 <p>Either way, AI bug reports like this are about as welcome as a haemorrhage in a jacuzzi.</p>
375 </body></html>]]></content>
376
377 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/#comments" thr:count="2" />
378 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/grinding-down-open-source-maintainers-with-ai/feed/atom/" thr:count="2" />
379 <thr:total>2</thr:total>
380 </entry>
381 <entry>
382 <author>
383 <name>@edent</name>
384 </author>
385
386 <title type="html"><![CDATA[Get the location of the ISS using DNS]]></title>
387 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/" />
388
389 <id>https://shkspr.mobi/blog/?p=61693</id>
390 <updated>2025-07-06T07:51:14Z</updated>
391 <published>2025-07-06T11:34:33Z</published>
392 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="dns" /><category scheme="https://shkspr.mobi/blog" term="internet" /><category scheme="https://shkspr.mobi/blog" term="trivia" />
393 <summary type="html"><![CDATA[I love DNS esoterica. Weird little things that you can shove in the global directory to be distributed around the world instantly(ish). Domain names, like www.example.com usually resolve to servers. As much as we think of "the cloud" as being some intangible morass of ethereal Turing-machines floating in probability space, the more prosaic reality is that they're just boxen in data centres. They …]]></summary>
394
395 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/"><![CDATA[
396 <html><head></head><body><p>I love DNS esoterica. Weird little things that you can shove in the global directory to be distributed around the world instantly(ish).</p>
397
398 <p>Domain names, like <code>www.example.com</code> usually resolve to servers. As much as we think of "the cloud" as being some intangible morass of ethereal Turing-machines floating in probability space, the more prosaic reality is that they're just boxen in data centres. They have a physical location.</p>
399
400 <p>Got a tricky machine which is playing silly-buggers? Wouldn't it be nice to know exactly where it is? That way you can visit and give it some <a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/PercussiveMaintenance">percussive maintenance</a>.</p>
401
402 <p>Enter the DNS LOC record!</p>
403
404 <p>The snappily titled <a href="https://www.rfc-editor.org/rfc/rfc1876.html">RFC 1876</a> is an <em>experimental</em> standard. It allows you to create a DNS record which specifies the latitude and longitude of your server. Of course, some data-centres are very tall and some are underground. So it also contains an altitude parameter.</p>
405
406 <p>The standard allows for a minimum altitude of -100,000 metres - deep enough for any bunker! The maximum altitude is 42,849,672 metres which is high enough to allow it to be used on <a href="https://www.esa.int/Enabling_Support/Space_Transportation/Types_of_orbits#GEO">satellites in geostationary orbit</a>.</p>
407
408 <p>So, as a bit of fun, I decided to create <code>where-is-the-iss.dedyn.io</code></p>
409
410 <p>It isn't a website. You can't ping it. There's no way to interact with it <em>except</em> by using DNS. Yup! You can use a DNS query to get the (approximate) location of the International Space Station!</p>
411
412 <p>Linux and Mac users<sup id="fnref:win"><a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fn:win" class="footnote-ref" title="I don't think there's a way for Windows users to look up LOC records using PowerShell or the Command Prompt." role="doc-noteref">0</a></sup> can run:</p>
413
414 <p><code>dig where-is-the-iss.dedyn.io LOC</code></p>
415
416 <p>And receive back the latest position of the ISS:</p>
417
418 <pre><code class="language-_">;; ANSWER SECTION:
419 where-is-the-iss.dedyn.io. 1066 IN LOC 47 24 53.500 N 66 12 12.070 W 430520m 10000m 10000m 10000m
420 </code></pre>
421
422 <p>The DNS records are updated every 15 minutes on a best-effort basis<sup id="fnref:nasa"><a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fn:nasa" class="footnote-ref" title="Look, I'm not NASA, OK? If you're using this to help you dock then I cannot be held responsible." role="doc-noteref">1</a></sup>.</p>
423
424 <h2 id="how"><a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#how" class="heading-link">How</a></h2>
425
426 <p>The lovely people at <a href="https://www.n2yo.com">N2YO</a> have a website which allows you to track <em>loads</em> of objects in orbit. They also have an <a href="https://www.n2yo.com/api/">easy to use API</a> with a generous free tier.</p>
427
428 <p>Calling <code>https://api.n2yo.com/rest/v1/satellite/positions/25544/0/0/0/1/&apiKey=_____</code> gets back the latest position:</p>
429
430 <pre><code class="language-json">{
431 "info": {
432 "satname": "SPACE STATION",
433 "satid": 25544,
434 "transactionscount": 7
435 },
436 "positions": [
437 {
438 "satlatitude": -21.25409321,
439 "satlongitude": 140.3335763,
440 "sataltitude": 420.09,
441 "azimuth": 292.92,
442 "elevation": -70.95,
443 "ra": 202.69300845,
444 "dec": -32.16097472,
445 "timestamp": 1751366048,
446 "eclipsed": true
447 }
448 ]
449 }
450 </code></pre>
451
452 <p>Note that the altitude is in Km, whereas the LOC format requires m.</p>
453
454 <p>The latitude and longitude are in decimal format - they need to be converted to Degrees, Minutes, and Seconds.</p>
455
456 <p>There were only a few free domain name providers who offer an API for updating LOC records. I went for <a href="https://desec.io/">deSEC</a> a charity from Berlin. They have <a href="https://desec.readthedocs.io/en/latest/">comprehensive API documentation</a>.</p>
457
458 <p>Adding the initial LOC record is done with:</p>
459
460 <pre><code class="language-bash">curl https://desec.io/api/v1/domains/where-is-the-iss.dedyn.io/rrsets/ \
461 --header "Authorization: Token _______" \
462 --header "Content-Type: application/json" --data @- <<< \
463 '{"type": "LOC", "records": ["40 16 25.712 S 29 32 36.243 W 427550m 0.00m 10000m 10m"], "ttl": 900}'
464 </code></pre>
465
466 <p>However, updating the record is a little trickier. it needs to be sent as an <a href="https://desec.readthedocs.io/en/latest/dns/rrsets.html#modifying-an-rrset">HTTP PATCH</a> to a subtly different URl. The PATCH only needs to send the data which have changed.</p>
467
468 <pre><code class="language-bash">curl -X PATCH https://desec.io/api/v1/domains/where-is-the-iss.dedyn.io/rrsets/@/LOC/ \
469 --header "Authorization: Token _______" \
470 --header "Content-Type: application/json" --data @- <<< \
471 '{"records": ["40 16 25.712 S 29 32 36.243 W 427550m 0.00m 10000m 10m"]}'
472 </code></pre>
473
474 <p>I set the <a href="https://ttl-calc.com/">Time To Live</a> at 900 seconds. Every 15 minutes my code runs to update the record<sup id="fnref:api"><a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fn:api" class="footnote-ref" title="I suppose you could build an API with unlimited request limits by distributing data via DNS TXT records. Would best suit static or infrequently updating data. Push it once to DNS and let everyone…" role="doc-noteref">2</a></sup>. That keeps me well within the API limits for both services. I could add TXT records showing when it was last updated, or other sorts of unstructured data, but I think this is enough for a quick proof-of-concept.</p>
475
476 <p>There you have it! A complex and silly way to demonstrate how DNS can be used to hold the most unlikely of records<sup id="fnref:naptr"><a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fn:naptr" class="footnote-ref" title="See if you can find the other interesting record I've added to DNS!" role="doc-noteref">3</a></sup>. Say, I wonder how you'd represent the co-ordinates of the Mars Rover…?</p>
477
478 <h2 id="further-reading"><a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#further-reading" class="heading-link">Further Reading</a></h2>
479
480 <p>For more DNS weirdness, please see my other posts:</p>
481
482 <ul>
483 <li><a href="https://shkspr.mobi/blog/2022/08/dns-esoterica-bimi-svg-in-dns-txt-wtf/">BIMI - SVG in DNS TXT WTF?!</a></li>
484 <li><a href="https://shkspr.mobi/blog/2022/07/dns-esoterica-why-you-cant-dig-switzerland/">Why you can't dig Switzerland</a></li>
485 </ul>
486
487 <div class="footnotes" role="doc-endnotes">
488 <hr>
489 <ol start="0">
490
491 <li id="fn:win" role="doc-endnote">
492 <p>I don't think there's a way for Windows users to look up LOC records using PowerShell or the Command Prompt. <a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fnref:win" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
493 </li>
494
495 <li id="fn:nasa" role="doc-endnote">
496 <p>Look, I'm not NASA, OK? If you're using this to help you dock then I cannot be held responsible. <a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fnref:nasa" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
497 </li>
498
499 <li id="fn:api" role="doc-endnote">
500 <p>I suppose you could build an API with unlimited request limits by distributing data via DNS TXT records. Would best suit static or infrequently updating data. Push it once to DNS and let everyone query it semi-locally. <a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fnref:api" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
501 </li>
502
503 <li id="fn:naptr" role="doc-endnote">
504 <p>See if you can find the other interesting record I've added to DNS! <a href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#fnref:naptr" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
505 </li>
506
507 </ol>
508 </div>
509 </body></html>]]></content>
510
511 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/#comments" thr:count="11" />
512 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/get-the-location-of-the-iss-using-dns/feed/atom/" thr:count="11" />
513 <thr:total>11</thr:total>
514 </entry>
515 <entry>
516 <author>
517 <name>@edent</name>
518 </author>
519
520 <title type="html"><![CDATA[Book Review: The Department of Rare Books and Special Collections - Eva Jurczyk ★☆☆☆☆]]></title>
521 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-the-department-of-rare-books-and-special-collections-eva-jurczyk/" />
522
523 <id>https://shkspr.mobi/blog/?p=61430</id>
524 <updated>2025-07-01T09:16:33Z</updated>
525 <published>2025-07-05T11:34:47Z</published>
526 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Book Review" />
527 <summary type="html"><![CDATA[I did not care for this book at all. It is a dreary crime novel where - shock! horror! - someone has stolen a book. And, yes, it is the obvious suspect. Much like The Martian Contingency I found the lead character profoundly irritating. A miserable protagonist who is completely ineffectual and refuses to take even the most minor of actions. Her self-loathing drips off the page and smothers any…]]></summary>
528
529 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/book-review-the-department-of-rare-books-and-special-collections-eva-jurczyk/"><![CDATA[
530 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/9781728246598_1.webp" alt="Book cover." width="200" class="alignleft size-full wp-image-61431">I did not care for this book at all. It is a dreary crime novel where - shock! horror! - someone has stolen a book. And, yes, it is the obvious suspect.</p>
531
532 <p>Much like <a href="https://shkspr.mobi/blog/2025/06/book-review-the-martian-contingency-by-mary-robinette-kowal/">The Martian Contingency</a> I found the lead character profoundly irritating. A miserable protagonist who is completely ineffectual and refuses to take even the most minor of actions. Her self-loathing drips off the page and smothers any character development.</p>
533
534 <p>At various points she's "Ashamed, embarrassed, disgusted with herself" or regards anything she does as "the useless action of a helpless woman" and reflects that "She had never been beautiful." It is a chore to be inside her head. I don't expect to empathise with every literary protagonist, but there's hardly anything about this woman which isn't driven by her neuroses - it felt like I was an unwilling voyeur in a psychotherapy session.</p>
535
536 <p>The prose was plodding and there are some excruciating attempts at exposition. After the whodunnit is revealed (literally the only person who it could be) the book inexplicably carries on for a few more chapters.</p>
537 </body></html>]]></content>
538
539 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-the-department-of-rare-books-and-special-collections-eva-jurczyk/#comments" thr:count="0" />
540 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/book-review-the-department-of-rare-books-and-special-collections-eva-jurczyk/feed/atom/" thr:count="0" />
541 <thr:total>0</thr:total>
542 </entry>
543 <entry>
544 <author>
545 <name>@edent</name>
546 </author>
547
548 <title type="html"><![CDATA[Making My Own Hacktoberfest T-Shirts]]></title>
549 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/" />
550
551 <id>https://shkspr.mobi/blog/?p=61656</id>
552 <updated>2025-07-04T11:29:23Z</updated>
553 <published>2025-07-04T11:34:54Z</published>
554 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="hacking" /><category scheme="https://shkspr.mobi/blog" term="Hacktoberfest" /><category scheme="https://shkspr.mobi/blog" term="t-shirt" />
555 <summary type="html"><![CDATA[Between 2014 and 2022, DigitalOcean sent free t-shirts to developers who completed the Hacktoberfest challenge. For entirely sensible reasons related to sustainability and spammy entrants, they stopped doing physical merchandise in 2023. I'm the sort of hip fashionista who only wears free conference t-shirts. GDS@GDSTeamWe support open source. And we’ve got the t-shirts to prove it (thanks @…]]></summary>
556
557 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/"><![CDATA[
558 <html><head></head><body><p>Between 2014 and 2022, DigitalOcean sent free t-shirts to developers who completed the Hacktoberfest challenge. For entirely sensible reasons related to sustainability and spammy entrants, they stopped doing physical merchandise in 2023.</p>
559
560 <p>I'm the sort of hip fashionista who <em>only</em> wears free conference t-shirts.</p>
561
562 <blockquote class="social-embed" id="social-embed-958377102641893376" lang="en" itemscope="" itemtype="https://schema.org/SocialMediaPosting"><header class="social-embed-header" itemprop="author" itemscope="" itemtype="https://schema.org/Person"><a href="https://twitter.com/GDSTeam" class="social-embed-user" itemprop="url"><img class="social-embed-avatar social-embed-avatar-circle" src="data:image/webp;base64,UklGRt4BAABXRUJQVlA4INIBAADQCACdASowADAAPrVKn0snJCMhpzgO2OAWiWwAtGOAQADeTUO3VAHt3+mUAa8vVV0OeXOkLkf2mNAwlnwjfbQGeO/oPw0QIE22U14pwqAAAP7tg4IpPv/wQXUHnW8H/7dn/+yAf/ZAP6fcAEAEOr0lN3rLmM+Wk1up6N+kazcl/Abt270AvZTfvE6X1RSsD+z5eBziALv0ORrElnCWCSLc6vPOi3N5FglKAuXQAJ/1e1jT7ZJM4RrWz4wEgm4/y4wDKMv0sEtbYY0anAWPE2MDs7mHpT6aRffkb7fchUdIQ3jUKmSMNXCJ5o6681y5TBHnnbV5MuKUg5//65SApSbC5xnIWFGYATe4t3TsrQRe8zzxFYDXFFpX6Z90BYKkAYpsqlqtMeyJTJqLPbTBIuzYxyyMvxuGyHGOuHzWDB7rPST6uWBuJuV8Asv2q4bplPml3lZ8bIVgydoxCMzGFbGNa1OfWD0c2gA7kXc+vylSPJ8Z04z4qBxi8CWMAfBjarrwQEL2pXq2Jaoy+Z/MoO9geakW1YK9F5+Dth7nHl/mf0o5q3iaS3GWQ2jofNMmfSosmGpxfQYRuDp+kWt3nKiMR93BZNVqULfhgV1+FkmTyAAA" alt="" itemprop="image"><div class="social-embed-user-names"><p class="social-embed-user-names-name" itemprop="name">GDS</p>@GDSTeam</div></a><img class="social-embed-logo" alt="Twitter" src="data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%0Aaria-label%3D%22Twitter%22%20role%3D%22img%22%0AviewBox%3D%220%200%20512%20512%22%3E%3Cpath%0Ad%3D%22m0%200H512V512H0%22%0Afill%3D%22%23fff%22%2F%3E%3Cpath%20fill%3D%22%231d9bf0%22%20d%3D%22m458%20140q-23%2010-45%2012%2025-15%2034-43-24%2014-50%2019a79%2079%200%2000-135%2072q-101-7-163-83a80%2080%200%200024%20106q-17%200-36-10s-3%2062%2064%2079q-19%205-36%201s15%2053%2074%2055q-50%2040-117%2033a224%20224%200%2000346-200q23-16%2040-41%22%2F%3E%3C%2Fsvg%3E"></header><section class="social-embed-text" itemprop="articleBody">We support open source. And we’ve got the t-shirts to prove it (thanks <a href="https://twitter.com/github">@github</a> <a href="https://twitter.com/digitalocean">@digitalocean</a>). GDS took part in <a href="https://twitter.com/hashtag/Hacktoberfest">#Hacktoberfest</a> this year, contributing to open source projects as part of a global community <a href="https://hacktoberfest.digitalocean.com/">hacktoberfest.digitalocean.com</a> <a href="https://x.com/gdsteam/status/958377102641893376/photo/1">pic.x.com/AkM09LGono</a><div class="social-embed-media-grid"><a href="https://pbs.twimg.com/media/DUzWotoW0AAFMmK.jpg" class="social-embed-media-link"><img class="social-embed-media" alt="Terence, Andrea and Anna wearing Hacktoberfest t-shirts" src="data:image/webp;base64,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"></a></div></section><hr class="social-embed-hr"><footer class="social-embed-footer"><a href="https://twitter.com/GDSTeam/status/958377102641893376"><span aria-label="24 likes" class="social-embed-meta"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/2764.png" alt="❤" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 24</span><span aria-label="3 replies" class="social-embed-meta"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f4ac.png" alt="💬" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 3</span><span aria-label="0 reposts" class="social-embed-meta"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/1f501.png" alt="🔁" class="wp-smiley" style="height: 1em; max-height: 1em;" /> 0</span><time datetime="2018-01-30T16:31:21.000Z" itemprop="datePublished">16:31 - Tue 30 January 2018</time></a></footer></blockquote>
563
564 <p>Sadly, after several years of constant catwalk modelling, my beloved Hacktoberfest shirts are full of holes. I couldn't find any for sale on eBay or Vinted - so I decided to make my own.</p>
565
566 <p>Note: <a href="https://github.com/Hacktoberfest/hacktoberfest-2022/blob/main/src/assets/brand-guidelines.pdf">DigitalOcean's Brand Guidelines</a> say that you shouldn't create physical merchandise or sell any products featuring the logo. Well, I'm not selling these nor, do I think, they are merchandise. Hacktoberfest aren't using these to incentivise anyone any more. They're just cool t-shirts.</p>
567
568 <h2 id="the-logos"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#the-logos" class="heading-link">The Logos</a></h2>
569
570 <p>There are <a href="https://dev.to/fernandezbaptiste/last-10-years-of-hacktoberfest-merch-a-journey-through-time-8od">lots of photos of the t-shirts</a> but it is surprisingly hard to find the original assets.</p>
571
572 <h3 id="low-resolution"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#low-resolution" class="heading-link">Low Resolution</a></h3>
573
574 <p>Kotis - a design agency - did the Hacktoberfest swag from 2015-2020. They have a <a href="https://go.kotisdesign.com/portfolio/digital-ocean-hacktoberfest/">brand portfolio</a> with the t-shirt icons. Sadly, all a bit low resolution for printing, but good for getting accurate background colours for the material.</p>
575
576 <ul>
577 <li>2020 <img src="https://go.kotisdesign.com/wp-content/uploads/2020/02/Artboard-18.png" alt=""></li>
578 <li>2019 <img src="https://go.kotisdesign.com/wp-content/uploads/2020/02/Artboard-19.png" alt=""></li>
579 <li>2018 <img src="https://go.kotisdesign.com/wp-content/uploads/2020/02/Artboard-20.png" alt=""></li>
580 <li>2017 <img src="https://go.kotisdesign.com/wp-content/uploads/2020/02/Artboard-21.png" alt=""></li>
581 <li>2016 <img src="https://go.kotisdesign.com/wp-content/uploads/2020/02/Artboard-22.png" alt=""></li>
582 <li>2015 <img src="https://go.kotisdesign.com/wp-content/uploads/2020/02/Artboard-23.png" alt=""></li>
583 </ul>
584
585 <p>Similarly, there are a few low resolution promo shots of the t-shirts or their logos:</p>
586
587 <ul>
588 <li><a href="https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2f1eggqi7zgs0cj38j2p.jpg">2022</a> (back of t-shirt)</li>
589 <li><a href="https://user-images.githubusercontent.com/99407553/194741467-af241be9-e0df-4f43-88a8-9236a253a555.jpg">2021</a> (t-shirt)</li>
590 <li><a href="https://cerealtree.wordpress.com/wp-content/uploads/2016/11/hacktober.png">2016</a> (more accurate colours)</li>
591 <li><a href="https://github.blog/wp-content/uploads/2015/09/d13f20be-66f9-11e5-8478-992126efc469.png">2015</a> (logo)</li>
592 <li><a href="https://hacktoberfesthowto.github.io/images/2014Logo.webp">2014</a> (logo)</li>
593 </ul>
594
595 <p>AI upscaling looked typically rubbish.</p>
596
597 <h3 id="higher-resolution-bitmaps"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#higher-resolution-bitmaps" class="heading-link">Higher Resolution Bitmaps</a></h3>
598
599 <p>Some designers have their logo designs on Dribbble. Not <em>very</em> high resolution, but good enough for stickers.</p>
600
601 <ul>
602 <li><a href="https://dribbble.com/shots/8192199-Hacktoberfest-2019-logo">2019</a></li>
603 <li><a href="https://dribbble.com/shots/5333694-Hacktoberfest-2018">2018</a></li>
604 <li><a href="https://dribbble.com/shots/3814307-Hactoberfest-2017">2017</a></li>
605 <li><a href="https://dribbble.com/shots/2988111-Hactoberfest-2016">2016</a></li>
606 </ul>
607
608 <h3 id="archived-logos"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#archived-logos" class="heading-link">Archived Logos</a></h3>
609
610 <p>The official Hacktoberfest website had some logos embedded on it:</p>
611
612 <ul>
613 <li><a href="https://web.archive.org/web/20221001041836/https://hacktoberfest.com/">2022</a> (SVG logo)</li>
614 <li><a href="https://web.archive.org/web/20190930141101im_/https://hacktoberfest.digitalocean.com/assets/logo-hf19-full-10f3c000cea930c76acc1dedc516ea7118b95353220869a3051848e45ff1d656.svg">2019</a> (SVG)</li>
615 <li><a href="https://web.archive.org/web/20181001075142if_/https://hacktoberfest.digitalocean.com/assets/logo-hacktoberfest-658b5aa2bd34e782d29c40bf6afbdff00f20fe1328efa6da17743878ba8db66f.png">2018</a> (PNG with transparent background)</li>
616 <li><a href="https://web.archive.org/web/20170913052813/https://hacktoberfest.digitalocean.com/">2017</a> (SVG)</li>
617 </ul>
618
619 <h2 id="best-of-the-bunch"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#best-of-the-bunch" class="heading-link">Best of the bunch</a></h2>
620
621 <p>These are the best available logos. The SVGs are suitable for printing at any size, the PNGs may be harder.</p>
622
623 <ul>
624 <li><a href="https://static.wikia.nocookie.net/logopedia/images/7/7f/Hacktoberfest_icon_2022.svg">2022</a> (SVG logo)</li>
625 <li><a href="https://github.com/Hacktoberfest/hacktoberfest-2020/blob/master/app/assets/images/HF-full-logo.svg">2020</a> (SVG)</li>
626 <li><a href="//web.archive.org/web/20190930141101im_/https://hacktoberfest.digitalocean.com/assets/logo-hf19-full-10f3c000cea930c76acc1dedc516ea7118b95353220869a3051848e45ff1d656.svg">2019</a> (SVG)</li>
627 <li><a href="https://hacktoberfesthowto.github.io/images/2018Logo.webp">2018</a> (WebP 1155x898)</li>
628 <li><a href="//web.archive.org/web/20170913052813/https://hacktoberfest.digitalocean.com/">2017</a> (SVG embedded in page)</li>
629 <li><a href="//web.archive.org/web/20161022114022im_/https://hacktoberfest.digitalocean.com/assets/h-ceffbf9c09a918a4eda57f3a80f70e71b778ae233ece6f0ce41105316ddd3a64.svg">2016</a> (SVG)</li>
630 </ul>
631
632 <h2 id="missing"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#missing" class="heading-link">Missing</a></h2>
633
634 <p>The following are missing 2014, 2015, 2021, 2022 (comic). There are photos of the shirts, and some low-resolution artwork available, all of which are too low quality to be printed. If you know how to get high-resolution images of them - please leave a comment!</p>
635
636 <h3 id="2021"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#2021" class="heading-link">2021</a></h3>
637
638 <p>There are <em>some</em> elements out there. For example:</p>
639
640 <ul>
641 <li><a href="https://www.behance.net/gallery/128630281/HacktoberFest-2021">This Behance profile of Hacktoberfest 2021</a></li>
642 <li><a href="https://web.archive.org/web/20210930065625im_/https://hacktoberfest.digitalocean.com/_nuxt/img/logo-hacktoberfest-full.f42e3b1.svg">The official logo</a></li>
643 <li><a href="https://web.archive.org/web/20210928150155im_/https://hacktoberfest.digitalocean.com/_nuxt/img/logo-hacktoberfest-full2.aa1e9d9.svg">The logo with the t-shirt colour scheme</a></li>
644 <li><a href="https://web.archive.org/web/20210928150151/https://hacktoberfest.digitalocean.com/brandguidelines">The brand guidelines</a> for more accurate colour reproduction.</li>
645 </ul>
646
647 <h3 id="2014"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#2014" class="heading-link">2014</a></h3>
648
649 <p>There's not much available about the first t-shirt. There's a <a href="https://hacktoberfesthowto.github.io/images/2014Logo.webp">version of the logo used</a> and <a href="https://community.nodebb.org/topic/2948/digital-ocean-free-t-shirts">some photos</a> but that's about it.</p>
650
651 <h2 id="photos-of-t-shirts"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#photos-of-t-shirts" class="heading-link">Photos of T-Shirts</a></h2>
652
653 <p>If you want to compare the logos to the originals, and see what colour fabric they used, there are lots of photo online:</p>
654
655 <ul>
656 <li><a href="https://www.reddit.com/r/hacktoberfest/comments/16vzkes/here_is_my_collection_which_design_is_your/">Reddit collection</a></li>
657 <li><a href="https://hacktoberfesthowto.github.io/history/">History of Hacktoberfest</a></li>
658 </ul>
659
660 <h2 id="end-result"><a href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#end-result" class="heading-link">End Result</a></h2>
661
662 <p>If I can't find the missing logos, I'll create my own design for my own personal use. Something like this:</p>
663
664 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/07/double-t.webp" alt="Two t-shirts with the various Hacktoberfest logos stacked on them." width="1024" height="464" class="aligncenter size-full wp-image-61672">
665
666 <p>If you have a source for vectors of the missing logos, please drop me a comment.</p>
667 </body></html>]]></content>
668
669 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/#comments" thr:count="2" />
670 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/making-my-own-hacktoberfest-t-shirts/feed/atom/" thr:count="2" />
671 <thr:total>2</thr:total>
672 </entry>
673 <entry>
674 <author>
675 <name>@edent</name>
676 </author>
677
678 <title type="html"><![CDATA[Process Vs Prejudice]]></title>
679 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/process-vs-prejudice/" />
680
681 <id>https://shkspr.mobi/blog/?p=60985</id>
682 <updated>2025-07-01T09:16:31Z</updated>
683 <published>2025-07-03T11:34:05Z</published>
684 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="forms" /><category scheme="https://shkspr.mobi/blog" term="politics" />
685 <summary type="html"><![CDATA[I recently read an interesting article about Accountability Sinks. In it, the author argues that part of the reason for having business processes is that they diffuse accountability. Every one of us has tried to have an argument with an employee of a big company, and it always goes like this: the human being you are speaking to is only allowed to follow a set of processes and rules that pass on …]]></summary>
686
687 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/process-vs-prejudice/"><![CDATA[
688 <html><head></head><body><p>I recently read an interesting article about <a href="https://250bpm.substack.com/p/accountability-sinks">Accountability Sinks</a>. In it, the author argues that part of the reason for having business processes is that they diffuse accountability.</p>
689
690 <p>Every one of us has tried to have an argument with an employee of a big company, and it always goes like this:</p>
691
692 <blockquote><p>the human being you are speaking to is only allowed to follow a set of processes and rules that pass on decisions made at a higher level of the corporate hierarchy. It’s often a frustrating experience; you want to get angry, but you can’t really blame the person you’re talking to.</p></blockquote>
693
694 <p>So should we give people more discretion in which processes they follow?</p>
695
696 <p>In some cases, yes! The article contains some compelling examples of when "breaking the rules" is the preferable outcome.</p>
697
698 <p>But there are some unacknowledged downsides to letting people decide which rules are applicable - and that's people's personal prejudices.</p>
699
700 <p>The article say some of the discontent with the modern world can be blamed on over-adherence to rules. For example:</p>
701
702 <blockquote><p>The skepticism toward judges? It fits. They often seem more devoted to procedure than to justice.</p></blockquote>
703
704 <p>Imagine a world without <a href="https://www.sentencingcouncil.org.uk/sentencing-and-the-council/about-sentencing-guidelines/">sentencing guidelines</a>. Perhaps the judge is from a different tribe to the accused and punishes them much more harshly than a clan-member. Would that seem fair?</p>
705
706 <p>The customer service agent just doesn't like people of your gender, and refuses to process your refund.</p>
707
708 <p>You give the bank manager a firm handshake and he approves your loan - even though you don't <em>technically</em> qualify you look like a decent sort of chap.</p>
709
710 <p>And on it goes.</p>
711
712 <p>Look, there's no doubt plenty of bias encoded within processes. All processes should be regularly reviewed and updated. Breaking a process in extremis can be a good idea. When confronted with an inflexible policy, you may feel like a mere cog in a machine - but at least the machine is prevented from discriminating against your type of cogs.</p>
713
714 <p>A well-defined process dehumanises <em>both</em> sides.</p>
715 </body></html>]]></content>
716
717 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/process-vs-prejudice/#comments" thr:count="6" />
718 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/process-vs-prejudice/feed/atom/" thr:count="6" />
719 <thr:total>6</thr:total>
720 </entry>
721 <entry>
722 <author>
723 <name>@edent</name>
724 </author>
725
726 <title type="html"><![CDATA[Book Review: The World According to Cunk - An Illustrated History of All World Events Ever, Space Permitting by Philomena Cunk ★★★★★]]></title>
727 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-the-world-according-to-cunk-an-illustrated-history-of-all-world-events-ever-space-permitting-by-philomena-cunk/" />
728
729 <id>https://shkspr.mobi/blog/?p=61157</id>
730 <updated>2025-06-25T08:30:28Z</updated>
731 <published>2025-07-02T11:34:17Z</published>
732 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Book Review" /><category scheme="https://shkspr.mobi/blog" term="comedy" />
733 <summary type="html"><![CDATA[There are some characters whose tone of voice is inimitable. You cannot fail to read this without Diane Morgan's languid cadence echoing in your big empty head. The book has been written with a very specific pace - one chuckle per paragraph, a big laugh every page, and a set number of uncontrollable giggles per chapter. Somewhat formulaic, but highly effective. I kept highlighting bits of it…]]></summary>
734
735 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/book-review-the-world-according-to-cunk-an-illustrated-history-of-all-world-events-ever-space-permitting-by-philomena-cunk/"><![CDATA[
736 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/hbg-title-the-world-according-to-cunk-3-5.webp" alt="Book cover with famous people on the front." width="200" class="alignleft size-full wp-image-61158">There are some characters whose tone of voice is inimitable. You cannot fail to read this without Diane Morgan's languid cadence echoing in your big empty head.</p>
737
738 <p>The book has been written with a very specific pace - one chuckle per paragraph, a big laugh every page, and a set number of uncontrollable giggles per chapter. Somewhat formulaic, but highly effective.</p>
739
740 <p>I kept highlighting bits of it and showing them to my wife. After the 8th or 9th time she grabbed her own copy and started showing me the bits she found funny.</p>
741
742 <p>It's just endlessly quotable. "The emperor eventually died and was buried with a load of clay figures – like Nick Park will be." and "a sort of naughty typewriter called the Enigma machine" still keep me guffawing.</p>
743
744 <p>The long-running callbacks are perfect, as are the inclusion of a few <a href="https://www.youtube.com/watch?v=zIsc6zirBSw">fan favourite jokes</a>.</p>
745
746 <p>Even the fucking <em>index</em> of this book is hilarious.</p>
747 </body></html>]]></content>
748
749 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/book-review-the-world-according-to-cunk-an-illustrated-history-of-all-world-events-ever-space-permitting-by-philomena-cunk/#comments" thr:count="0" />
750 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/book-review-the-world-according-to-cunk-an-illustrated-history-of-all-world-events-ever-space-permitting-by-philomena-cunk/feed/atom/" thr:count="0" />
751 <thr:total>0</thr:total>
752 </entry>
753 <entry>
754 <author>
755 <name>@edent</name>
756 </author>
757
758 <title type="html"><![CDATA[Are Brother's Insecure Printers Illegal in the UK?]]></title>
759 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/" />
760
761 <id>https://shkspr.mobi/blog/?p=61677</id>
762 <updated>2025-07-01T09:16:24Z</updated>
763 <published>2025-07-01T11:34:15Z</published>
764 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="CyberSecurity" /><category scheme="https://shkspr.mobi/blog" term="IoT" /><category scheme="https://shkspr.mobi/blog" term="law" /><category scheme="https://shkspr.mobi/blog" term="legal" /><category scheme="https://shkspr.mobi/blog" term="Legislation" />
765 <summary type="html"><![CDATA[Another day, another security disaster! This time, multiple printers from Brother have an unfixable security flaw. That's bad, obviously, but is it illegally bad? Let's take a look at details of the vulnerability: An unauthenticated attacker who knows the target device's serial number, can generate the default administrator password for the device. Recently, the UK brought in some laws aimed…]]></summary>
766
767 <content type="html" xml:base="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/"><![CDATA[
768 <html><head></head><body><p>Another day, another security disaster! This time, <a href="https://www.theverge.com/news/694877/brother-printers-security-flaw-password-vulnerability">multiple printers from Brother have an unfixable security flaw</a>. That's bad, obviously, but is it <em>illegally</em> bad<sup id="fnref:law"><a href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/#fn:law" class="footnote-ref" title="I'm not a lawyer. This is not legal advice. This is just my interpretation of what's going on. If in doubt, consult someone qualified." role="doc-noteref">0</a></sup>?</p>
769
770 <p>Let's take a look <a href="https://www.cve.org/CVERecord?id=CVE-2024-51978">at details of the vulnerability</a>:</p>
771
772 <blockquote><p>An unauthenticated attacker who knows the target device's serial number, can generate the default administrator password for the device.</p></blockquote>
773
774 <p>Recently, the UK brought in some laws aimed at strengthening consumer protection - the Product Security and Telecommunications Infrastructure act (PSTI). There's <a href="https://www.ncsc.gov.uk/blog-post/smart-devices-law">a readable summary on the National Cyber Security Centre's website</a>.</p>
775
776 <p>There are three interesting points to note in that blog post. The first is about passwords:</p>
777
778 <blockquote><p>The law means manufacturers must ensure that all their smart devices meet basic cyber security requirements. Specifically:</p>
779
780 <ol>
781 <li>The manufacturer must not supply devices that use default passwords, which can be easily discovered online, and shared.</li>
782 </ol></blockquote>
783
784 <p>Secondly, is a question of jurisdiction:</p>
785
786 <blockquote><p>Most smart devices are manufactured outside the UK, but the PSTI act also applies to all organisations importing or retailing products for the UK market. Failure to comply with the act is a criminal offence</p></blockquote>
787
788 <p>Thirdly, what is actually covered:</p>
789
790 <blockquote><p>The law applies to any ‘consumer smart device’ that connects either to the internet, or to a home network (for example by wifi).</p></blockquote>
791
792 <p>Is a WiFi enabled printer a "consumer smart device"? One of the things that techies find confusing is that the law is <em>not</em> code. It usually doesn't enumerate a definitive list of what is and what isn't in scope. It gives a general outline and then allows case-law to develop. This means laws don't need to be updated when someone invents, say, an Internet connected tinfoil dispenser.</p>
793
794 <p>Let's move beyond the consumer-friendly summary and go to the actual law. <a href="https://www.legislation.gov.uk/uksi/2023/1007/schedule/1/made">The Product Security and Telecommunications Infrastructure (Security Requirements for Relevant Connectable Products) Regulations 2023</a></p>
795
796 <blockquote><ol start="2">
797 <li><p>Passwords must be—</p>
798
799 <p>a. unique per product; or</p>
800
801 <p>b. defined by the user of the product.</p></li>
802 <li><p>Passwords which are unique per product must not be—</p>
803
804 <p>a. based on incremental counters;</p>
805
806 <p>b. based on or derived from publicly available information;</p>
807
808 <p>c. based on or derived from unique product identifiers, such as serial numbers, unless this is done using an encryption method, or keyed hashing algorithm, that is accepted as part of good industry practice;</p>
809
810 <p>d. otherwise guessable in a manner unacceptable as part of good industry practice.</p></li>
811 </ol></blockquote>
812
813 <p>How does this apply to the printers? Rapid7, who discovered the vulnerability, <a href="https://www.rapid7.com/blog/post/multiple-brother-devices-multiple-vulnerabilities-fixed/">have this to say about how it works</a>:</p>
814
815 <blockquote><p>[The vulnerability] allows an attacker to leak a serial number via the target's HTTP, HTTPS, and IPP services. However, should an attacker not be able to leverage [the vulnerability], a remote unauthenticated attacker can still discover a target device's serial number via either a PJL or SNMP query</p></blockquote>
816
817 <p>So, yes. The default password <em>is</em> unique but it can be automatically derived from the serial number. That serial number is available to anyone with a network connection to the printer.</p>
818
819 <p>But, do printers fall under the scope of this act?</p>
820
821 <p>The <a href="https://www.legislation.gov.uk/ukpga/2022/46/part/1/enacted#section-4">Product Security and Telecommunications Infrastructure Act 2022</a> says:</p>
822
823 <blockquote><p>4 Relevant connectable products</p>
824
825 <ol>
826 <li><p>In this Part “relevant connectable product” means a product that meets conditions A and B.</p></li>
827 <li><p>Condition A is that the product is—</p>
828
829 <p>A. an internet-connectable product, or</p>
830
831 <p>B. a network-connectable product.</p></li>
832 <li><p>Condition B is that the product is not an excepted product (see section 6).</p></li>
833 </ol></blockquote>
834
835 <p>It goes on to define what Internet-connectable means, along with some other clarifying details. But is there a get-out clause here? Are printers an "excepted product"?</p>
836
837 <blockquote><p>In this Part “excepted product” means a product of a description specified in regulations made by the Secretary of State.</p></blockquote>
838
839 <p>OK, let's look at <a href="https://www.legislation.gov.uk/uksi/2023/1007/schedule/3">the regulations</a>. I've expanded out the relevant bit:</p>
840
841 <blockquote><p>Schedule 3 Excepted connectable products</p>
842
843 <ol start="5">
844 <li><p>Computers</p>
845
846 <ol>
847 <li><p>Products are excepted under this paragraph if they are computers which are—</p>
848
849 <p>a. desktop computers;</p>
850
851 <p>b. laptop computers;</p>
852
853 <p>c. tablet computers which do not have the capability to connect to cellular networks.</p></li>
854 </ol></li>
855 </ol></blockquote>
856
857 <p>Nope! The Brother printers don't appear to be exempt<sup id="fnref:neil"><a href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/#fn:neil" class="footnote-ref" title="With thanks to m'learned colleague Neil Brown who came to much the same conclusion" role="doc-noteref">1</a></sup>. What's <a href="https://www.legislation.gov.uk/ukpga/2022/46/part/1/enacted#section-38">the <em>maximum</em> penalty</a> Brother could be subject to?</p>
858
859 <p>The greater of £10 million or 4% of worldwide <em>revenue</em>.</p>
860
861 <p>Ouch!</p>
862
863 <p>Of course, much like GDPR fines, these are headline grabbing numbers. The prosaic reality is that <a href="https://www.gov.uk/government/publications/safety-and-standards-enforcement-enforcement-policy">the enforcement policy is much more likely to suggest remedial steps</a>. Only the most flagrant transgressors are likely to be punished harshly<sup id="fnref:actions"><a href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/#fn:actions" class="footnote-ref" title="You can see the actions they've previously taken. Because PSTI is so new, there aren't any actions against insecure IoT devices - so we'll have to wait and see how they choose to proceed." role="doc-noteref">2</a></sup>.</p>
864
865 <p>So, to recap. The law says an Internet-connected device (including printers) must have a password which is not "based on or derived from publicly available information". As I understand it, having a serial-number based password is OK <em>as long as you don't publicise the serial number</em>. I expect that if it were printed on a sticker that would be fine. But because the serial can be discovered remotely, it fails at this point.</p>
866
867 <p>In Brother's (slight) defence, unless the user has specifically connected the printer to the Internet this is only a local vulnerability. Someone on the same network would be able to monkey around with the printer but, similarly, they could plug in a USB cable for some illicit printing or break it with a hammer. Any damage is confined to the LAN.</p>
868
869 <p>Should users change default passwords? Yes. But manufacturers have a legal duty to ensure that people who don't are still protected.</p>
870
871 <div class="footnotes" role="doc-endnotes">
872 <hr>
873 <ol start="0">
874
875 <li id="fn:law" role="doc-endnote">
876 <p>I'm not a lawyer. This is not legal advice. This is just my interpretation of what's going on. If in doubt, consult someone qualified. <a href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/#fnref:law" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
877 </li>
878
879 <li id="fn:neil" role="doc-endnote">
880 <p>With thanks to m'learned colleague <a href="https://decoded.legal/blog/2023/10/new-rules-for-people-making-importing-or-distributing-internet-connected-or-connectable-products-part-1/">Neil Brown who came to much the same conclusion</a> <a href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/#fnref:neil" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
881 </li>
882
883 <li id="fn:actions" role="doc-endnote">
884 <p>You can <a href="https://www.gov.uk/government/publications/opss-enforcement-actions">see the actions they've previously taken</a>. Because PSTI is so new, there aren't any actions against insecure IoT devices - so we'll have to wait and see how they choose to proceed. <a href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/#fnref:actions" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
885 </li>
886
887 </ol>
888 </div>
889 </body></html>]]></content>
890
891 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/#comments" thr:count="4" />
892 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/07/are-brothers-insecure-printers-illegal-in-the-uk/feed/atom/" thr:count="4" />
893 <thr:total>4</thr:total>
894 </entry>
895 <entry>
896 <author>
897 <name>@edent</name>
898 </author>
899
900 <title type="html"><![CDATA[Book Review: The Left Hand of Dog - Si Clarke ★★☆☆☆]]></title>
901 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-the-left-hand-of-dog-si-clarke/" />
902
903 <id>https://shkspr.mobi/blog/?p=61173</id>
904 <updated>2025-06-26T07:19:15Z</updated>
905 <published>2025-06-30T11:34:37Z</published>
906 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Book Review" />
907 <summary type="html"><![CDATA[I have to say, I did not get on with this book. The central conceit is that a sci-fi fan is abducted by aliens and their universal translator converts everything into understandable slang. So we get lots of warp factors, ansibles, dilithium crystals, and Hitchiker’s references. It makes the whole thing feel a bit cheap. OK, maybe it is a little silly when an author comes up with some t…]]></summary>
908
909 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/book-review-the-left-hand-of-dog-si-clarke/"><![CDATA[
910 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/left.webp" alt="Book cover featuring a person, their dog, and an interstellar tea-pot." width="200" height="300" class="alignleft size-full wp-image-61175"> I have to say, I did <em>not</em> get on with this book. The central conceit is that a sci-fi fan is abducted by aliens and their universal translator converts everything into understandable slang. So we get lots of warp factors, ansibles, dilithium crystals, and Hitchiker’s references. It makes the whole thing feel a bit cheap. OK, maybe it is a little silly when an author comes up with some technobabble instead of saying "make the jump to light-speed" - but readers appreciate the effort.</p>
911
912 <p>It's a daft enough story but the chuckles are few and far between.</p>
913
914 <p>Much like the <a href="https://shkspr.mobi/blog/tag/wayfarers/">Wayfarers books</a>, it wears its heart on its sleeve. I found that a delightful and refreshing aspect which is rarely seen in sci-fi.</p>
915
916 <p>But, in the end, I found the plot a bit too derivative to enjoy, and the shoe-horned references quickly became tiresome.</p>
917 </body></html>]]></content>
918
919 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-the-left-hand-of-dog-si-clarke/#comments" thr:count="0" />
920 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/book-review-the-left-hand-of-dog-si-clarke/feed/atom/" thr:count="0" />
921 <thr:total>0</thr:total>
922 </entry>
923 <entry>
924 <author>
925 <name>@edent</name>
926 </author>
927
928 <title type="html"><![CDATA[Contactless Payments with GrapheneOS]]></title>
929 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/" />
930
931 <id>https://shkspr.mobi/blog/?p=61636</id>
932 <updated>2025-06-28T20:36:24Z</updated>
933 <published>2025-06-29T11:34:57Z</published>
934 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="android" /><category scheme="https://shkspr.mobi/blog" term="google" /><category scheme="https://shkspr.mobi/blog" term="GrapheneOS" /><category scheme="https://shkspr.mobi/blog" term="nfc" />
935 <summary type="html"><![CDATA[Google's monopolistic stranglehold on Android results in poor experience for power-users, and artificially restricts choice for those who have older phones. For example, Google Wallet is the de facto way to use NFC payments on Android. There's one problem though - it only works with Google's Android. If you have the temerity to install a 3rd party Android OS - like the hyper-secure GrapheneOS - …]]></summary>
936
937 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/"><![CDATA[
938 <html><head></head><body><p>Google's monopolistic stranglehold on Android results in poor experience for power-users, and artificially restricts choice for those who have older phones. For example, Google Wallet is the <i lang="la">de facto</i> way to use NFC payments on Android. There's one problem though - it only works with <em>Google's</em> Android. If you have the temerity to install a 3rd party Android OS - like the hyper-secure <a href="https://grapheneos.org/">GrapheneOS</a> - you'll be locked out of it.</p>
939
940 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/GPay-fs8.png" alt="This device can't be set up to pay contactless. Your device doesn't meet pay contactless security standards. It may be rooted or running uncertified software." width="504" class="aligncenter size-full wp-image-61637">
941
942 <p>First of all, Google is lying. It <em>does</em> meet security standards and it is <em>not</em> rooted. I get that <a href="https://shkspr.mobi/blog/2023/05/the-limits-of-general-purpose-computation/">I have no right to run someone else's software in an environment they don't like</a>, but this is just misinformation. 3rd party OSes are often <em>more</em> secure that a stock OS which has been left to rot by an unresponsive manufacturer.</p>
943
944 <p>Anyway, here's how you can use contactless payments on Graphene.</p>
945
946 <h2 id="prerequisites"><a href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#prerequisites" class="heading-link">Prerequisites</a></h2>
947
948 <p>I'm going to tell you what I did. If you found another way, leave a comment or write your own blog post.</p>
949
950 <p>I'm using the latest version of Graphene (2025062000) with Play Services installed. The app is running in my main profile. None of the advanced app protection has been toggled for the app. NFC is on.</p>
951
952 <p>You will have to agree to <a href="https://www.curve.com/legal/privacy/">Curve's privacy policy</a>. And the privacy policy of your credit card. Look, if you're using Graphene, you're probably overly privacy sensitive. If you're concerned about The Man<img src="https://s.w.org/images/core/emoji/15.1.0/72x72/2122.png" alt="™" class="wp-smiley" style="height: 1em; max-height: 1em;" /> knowing that you used your card to buy a breakfast beer and then sharing that with 958 trusted partners, just use cash instead.</p>
953
954 <h2 id="install-curve"><a href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#install-curve" class="heading-link">Install Curve</a></h2>
955
956 <p><a href="https://www.curve.com/join#D4MK9ZKN">Here's a referral link to install Curve</a> - join and you get £10. Or, you can <a href="https://play.google.com/store/apps/details?id=com.imaginecurve.curve.prd">install directly from the Play Store</a>.</p>
957
958 <p>You'll need to create an account and pass KYC / AML checks. <a href="https://www.fca.org.uk/consumers/fca-firm-checker/firm-10456-925447">Curve are regulated by the FCA</a> so you should feel safe giving your details to them.</p>
959
960 <h2 id="add-a-card"><a href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#add-a-card" class="heading-link">Add a card</a></h2>
961
962 <p>Curve is a <em>virtual</em> card provider. So add your existing Visa or MasterCard to the app (no Amex). When you spend on Curve, you're actually spending on the underlying card you've added. Curve promise cheaper foreign exchange fees and a few other perks. But what we're really interested in is NFC payments.</p>
963
964 <h2 id="set-up-curve-pay"><a href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#set-up-curve-pay" class="heading-link">Set up Curve Pay</a></h2>
965
966 <p>On your app's dashboard, you should see a banner saying "Curve Pay is good to go!". If not, head into your account and set it up there.</p>
967
968 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/Good-to-go-fs8.png" alt="Curve dashboard." width="504" class="aligncenter size-full wp-image-61638">
969
970 <p>If it has all set up, you should see a welcome tutorial explaining how contactless works.</p>
971
972 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/Good-To-Go-fs8.png" alt="Animation showing how to hold your phone to an NFC payment terminal." width="504" class="aligncenter size-full wp-image-61639">
973
974 <h2 id="set-your-default-wallet"><a href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#set-your-default-wallet" class="heading-link">Set your default wallet</a></h2>
975
976 <p>On your phone, go to Settings → Connected devices → Connection Preferences → NFC → Contactless Payments.</p>
977
978 <p>Or, search your settings for Pay.</p>
979
980 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/Pay-Location-fs8.png" alt="Settings search page." width="504" class="aligncenter size-full wp-image-61640">
981
982 <p>Select your default wallet app - in this case, Curve.</p>
983
984 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/Default-Wallet-App-fs8.png" alt="List of available wallet apps." width="504" class="aligncenter size-full wp-image-61641">
985
986 <h2 id="pay-for-something"><a href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#pay-for-something" class="heading-link">Pay for something</a></h2>
987
988 <p>You need to make sure NFC is turned on before you can use NFC payments. I know that sounds obvious, but I forgot to do it the first time and got very confused.</p>
989
990 <p>Go to a local shop, pick up something, hand it to the merchant, wave your phone over the payment terminal like you are a technowizard from the future.</p>
991
992 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/Notification-fs8.png" alt="Notification showing I paid £3.95 for a sticky bun." width="504" class="aligncenter size-full wp-image-61642">
993
994 <p>Enjoy eating whatever you paid for!</p>
995
996 <h2 id="thats-it"><a href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#thats-it" class="heading-link">That's it!</a></h2>
997
998 <p>Once you're done, you can turn of NFC if you're paranoid.</p>
999
1000 <p>Apparently, <a href="https://justfollow.me.uk/@sborrill/114761774161342879">Curve also works with Garmin Smart Watches</a> - but I don't have one to test out.</p>
1001
1002 <p>If you've found this blog post useful, I'd be grateful if you signed up with <a href="https://www.curve.com/join#D4MK9ZKN">my referral link for Curve</a>.</p>
1003 </body></html>]]></content>
1004
1005 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/#comments" thr:count="6" />
1006 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/contactless-payments-with-grapheneos/feed/atom/" thr:count="6" />
1007 <thr:total>6</thr:total>
1008 </entry>
1009 <entry>
1010 <author>
1011 <name>@edent</name>
1012 </author>
1013
1014 <title type="html"><![CDATA[Book Review: First Contact - The Story of Our Obsession with Aliens by Becky Ferreira ★★★★⯪]]></title>
1015 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-first-contact-the-story-of-our-obsession-with-aliens-by-becky-ferreira/" />
1016
1017 <id>https://shkspr.mobi/blog/?p=61450</id>
1018 <updated>2025-06-26T07:19:06Z</updated>
1019 <published>2025-06-28T11:34:39Z</published>
1020 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Book Review" /><category scheme="https://shkspr.mobi/blog" term="NetGalley" />
1021 <summary type="html"><![CDATA[This is a cheerful and convivial look through the history of humanity's search for life "out there". It isn't an "ancient aliens" style book of nonsense, but rather a steady walk through what has actually happened - and what we hope might happen. It is a beautiful PDF which has been gorgeously typeset and lushly illustrated. So many fonts! Sure, it isn't brilliant for eInk but excellent for a…]]></summary>
1022
1023 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/book-review-first-contact-the-story-of-our-obsession-with-aliens-by-becky-ferreira/"><![CDATA[
1024 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/9781523527779_766925.webp" alt="Book cover showing a UFO and digital signals." width="200" class="alignleft size-full wp-image-61451"> This is a cheerful and convivial look through the history of humanity's search for life "out there". It isn't an "ancient aliens" style book of nonsense, but rather a steady walk through what has actually happened - and what we hope <em>might</em> happen.</p>
1025
1026 <p>It is a beautiful PDF which has been gorgeously typeset and lushly illustrated. So many fonts! Sure, it isn't brilliant for eInk but excellent for a tablet or any other full-colour screen.</p>
1027
1028 <p>The language is unpretentious and accessible. It's probably aimed towards the space-obsessed teen market, but I found it delightful.</p>
1029
1030 <blockquote><p>The authorities were decidedly unchill about all this philosophizing, however, and Anaxagoras was condemned to death for impiety—a charge based on his rejection of religious teachings—after he kept insisting the Sun was a hot and large natural object, not some hunky god driving a chariot across the sky.</p></blockquote>
1031
1032 <p>There aren't any inline references or footnotes - and links to images would be nice - but they're all all stuffed at the end if you want to find more.</p>
1033
1034 <p>It would have been nice if some of the examples were a <em>little</em> more fleshed out:</p>
1035
1036 <blockquote><p>Many cultures have imagined themselves as the descendants of celestial objects, or believed that they will ascend to the skies to join their ancestors after death.</p></blockquote>
1037
1038 <p>But it is an excellent jumping off point for anyone who wants to expand their horizons. The book isn't really in any chronological order so jumps around a fair bit. Full of fascinating titbits - especially radio silence day - and avoids the trap of sticking to just the USA cultural hegemony,</p>
1039
1040 <p>A great starting point for anyone who wants to get quickly acquainted with our (so far futile) attempts to discover alien life.</p>
1041
1042 <p>Many thanks to <a href="https://www.netgalley.com">NetGalley</a> for the preview copy - the book is on sale 30th September 2025.</p>
1043 </body></html>]]></content>
1044
1045 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-first-contact-the-story-of-our-obsession-with-aliens-by-becky-ferreira/#comments" thr:count="0" />
1046 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/book-review-first-contact-the-story-of-our-obsession-with-aliens-by-becky-ferreira/feed/atom/" thr:count="0" />
1047 <thr:total>0</thr:total>
1048 </entry>
1049 <entry>
1050 <author>
1051 <name>@edent</name>
1052 </author>
1053
1054 <title type="html"><![CDATA[Review: Octopus Home Mini - Real-Time Smart Meter Monitoring ★★☆☆☆]]></title>
1055 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/" />
1056
1057 <id>https://shkspr.mobi/blog/?p=61481</id>
1058 <updated>2025-06-27T08:51:38Z</updated>
1059 <published>2025-06-27T11:34:29Z</published>
1060 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="electricity" /><category scheme="https://shkspr.mobi/blog" term="energy" /><category scheme="https://shkspr.mobi/blog" term="HomeAssistant" /><category scheme="https://shkspr.mobi/blog" term="IoT" /><category scheme="https://shkspr.mobi/blog" term="Smart Home" />
1061 <summary type="html"><![CDATA[I unashamedly love my smart-meter. Rather than having my energy provider guesstimate my bill, or having to send manual readings each month, it automatically beams them back to its mothership. It also enables interesting things like variable energy tariffs. By design, the smart-meter is limited in how much data it can send back. You can choose to have readings sent monthly, weekly, daily, or…]]></summary>
1062
1063 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/"><![CDATA[
1064 <html><head></head><body><p>I unashamedly <em>love</em> my smart-meter. Rather than having my energy provider guesstimate my bill, or having to send manual readings each month, it automatically beams them back to its mothership. It also enables interesting things like variable energy tariffs.</p>
1065
1066 <p>By design, the smart-meter is limited in how much data it can send back. You can choose to have readings sent monthly, weekly, daily, or half-hourly. There's no option for minute-by-minute precision. That's useful from a privacy perspective - and no doubt makes the network engineering simpler - but slightly annoying from a home-monitoring perspective.</p>
1067
1068 <p>The smart-meter has the ability to send real-time information to a local device using the ZigBee network. If you have an in-home display (IHD) then you'll have seen just how accurate it is.</p>
1069
1070 <p>As I've discovered, <a href="https://shkspr.mobi/blog/2020/04/hacking-your-smart-meter-part-1-zigbee/">you can't just pair any-old ZigBee device to your meter</a>. Luckily, Octopus have sent me the "Mini". A little device which connects to the smart-meter and your home WiFi, then reports usage every 10 seconds. Let's put it through its paces.</p>
1071
1072 <h2 id="size"><a href="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/#size" class="heading-link">Size</a></h2>
1073
1074 <p>Mini by name, mini by nature!</p>
1075
1076 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/Mini.webp" alt="Tiny pink device." width="2738" height="1541" class="aligncenter size-full wp-image-61492">
1077
1078 <p>It's rare to find a device smaller than its plug. I half-wonder if they could have integrated it and just made it into a smartplug.</p>
1079
1080 <p>Annoyingly, it is <em>micro</em> USB. I am a USB-C maximalist. There's no reason this device shouldn't use the same cable as everything else I own.</p>
1081
1082 <h2 id="installation"><a href="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/#installation" class="heading-link">Installation</a></h2>
1083
1084 <p>Plug the Mini in - ideally within 5m of your smartmeter - and wait for the blinkenlight. Follow the in-app instructions. Because, like every modern device, it needs an app. You need to install the standard Octopus Android app, and can then add the Mini to your account and to your WiFi.</p>
1085
1086 <img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/24ghz.webp" alt="Warning about using 2.4GHz WiFi." width="490" height="367" class="aligncenter size-full wp-image-61493">
1087
1088 <p>Like all cheap IoT devices, it will only work on 2.4㎓, so you may need to adjust which network your phone is on.</p>
1089
1090 <h2 id="and-then"><a href="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/#and-then" class="heading-link">And then…</a></h2>
1091
1092 <p>That's it. Every 10 seconds it sends an update to Octopus. You can use the app or the website to view your current consumption or to see your last 5 minutes or last 30 minutes usage.</p>
1093
1094 <p><a href="https://blog.v-s-f.co.uk/2023/07/near-realtime-energy-consumption-data-with-octopus-home-mini/">If you're a dab-hand with the API, you can poll that</a>. Or you can connect it to HomeAssistant.</p>
1095
1096 <h2 id="downside"><a href="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/#downside" class="heading-link">Downside</a></h2>
1097
1098 <p>In theory this is nifty, but there are a few things I'm not keen on.</p>
1099
1100 <ul>
1101 <li>Export readings simply don't work for some brands of smart meter. That's an annoyance - my meter can send half-hourly readings for export, but the Mini just shows that I'm using zero Watts.</li>
1102 <li>No local connection. It sends the data to Octopus, so I have to use their API to get the data. I'd like the ability to stream it directly from the Mini.</li>
1103 <li>USB-micro. We live in the future. USB-C or GTFO!</li>
1104 </ul>
1105
1106 <p>Honestly, a bit disappointing. If you don't have solar panels - or your meter works correctly - this could be very useful. Even so, the lack of an local API is a bit of a buzzkill. Sadly, for my purposes, it isn't very useful.</p>
1107 </body></html>]]></content>
1108
1109 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/#comments" thr:count="6" />
1110 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/review-octopus-home-mini-real-time-smart-meter-monitoring/feed/atom/" thr:count="6" />
1111 <thr:total>6</thr:total>
1112 </entry>
1113 <entry>
1114 <author>
1115 <name>@edent</name>
1116 </author>
1117
1118 <title type="html"><![CDATA[Book Review: The Martian Contingency by Mary Robinette Kowal ★★★★☆]]></title>
1119 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-the-martian-contingency-by-mary-robinette-kowal/" />
1120
1121 <id>https://shkspr.mobi/blog/?p=61166</id>
1122 <updated>2025-06-24T11:46:55Z</updated>
1123 <published>2025-06-26T11:34:19Z</published>
1124 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Book Review" /><category scheme="https://shkspr.mobi/blog" term="Mary Robinette Kowal" />
1125 <summary type="html"><![CDATA[The Lady Astronaut books are an absolute triumph - it's just a shame that they've been somewhat overshadowed by the TV series "For All Mankind". They both follow a similar trajectory - what if women were an integral part of the early space race and helped us to colonise off-world? The books, thankfully, don't pad out as much as the rival show - this latest novel is tightly focussed and takes us …]]></summary>
1126
1127 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/book-review-the-martian-contingency-by-mary-robinette-kowal/"><![CDATA[
1128 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/jpg_rgb_0650h-5-416x636-1.jpg" alt="Book cover featuring Astronauts on Mars." width="200" class="alignleft size-full wp-image-61167"> The Lady Astronaut books are an absolute triumph - it's just a shame that they've been somewhat overshadowed by the TV series "For All Mankind". They both follow a similar trajectory - what if women were an integral part of the early space race and helped us to colonise off-world? The books, thankfully, don't pad out as much as the rival show - this latest novel is tightly focussed and takes us to the Mars base where <em>shenanigans</em> are afoot.</p>
1129
1130 <p>For a sci-fi nerd like me, it is total catnip. A heady mix of brain-tangling "what ifs" and the geeky joy of "<a href="https://tvtropes.org/pmwiki/pmwiki.php/Main/CompetencePorn">competency porn</a>". The language is gorgeous with some beautiful turns of phrase, and the pacing does an excellent job of ratcheting up the tension.</p>
1131
1132 <p>My only criticism is that Elma is <em>such</em> an ineffective character. She seems to forget that she's one of the most senior people on the mission and has the right - nay! the duty! - to get answers. Her lack of confidence isn't a quirky character flaw; it is a profoundly irritating co-star.</p>
1133
1134 <p>I love the world building, the jokey asides, and the sense of purpose all the characters have. The moral dilemmas and Politics are well articulated and don't feel tacked on. It's worth picking up the whole series.</p>
1135 </body></html>]]></content>
1136
1137 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-the-martian-contingency-by-mary-robinette-kowal/#comments" thr:count="2" />
1138 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/book-review-the-martian-contingency-by-mary-robinette-kowal/feed/atom/" thr:count="2" />
1139 <thr:total>2</thr:total>
1140 </entry>
1141 <entry>
1142 <author>
1143 <name>@edent</name>
1144 </author>
1145
1146 <title type="html"><![CDATA[Theatre Review: Just For One Day ★★★★⯪]]></title>
1147 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/theatre-review-just-for-one-day/" />
1148
1149 <id>https://shkspr.mobi/blog/?p=61592</id>
1150 <updated>2025-06-25T08:30:23Z</updated>
1151 <published>2025-06-25T11:34:07Z</published>
1152 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Theatre Review" />
1153 <summary type="html"><![CDATA[Leave your cynicism at the door. Jukebox musicals usually stick to a single-artist (Mamma Mia, & Juliet, Tommy). As a result, they all start to sound a bit samey after a few numbers. Shows like Return To The Forbidden planet shoe-horn in songs from a dozen artists without much regard to plot, tone, or pacing. Just For One Day goes down a different route. Rather than just recreate the famous…]]></summary>
1154
1155 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/theatre-review-just-for-one-day/"><![CDATA[
1156 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/JFOD.webp" alt="A crowd of singers." width="400" class="alignleft size-full wp-image-61593"> Leave your cynicism at the door.</p>
1157
1158 <p>Jukebox musicals usually stick to a single-artist (Mamma Mia, & Juliet, Tommy). As a result, they all start to sound a bit samey after a few numbers. Shows like Return To The Forbidden planet shoe-horn in songs from a dozen artists without much regard to plot, tone, or pacing.</p>
1159
1160 <p>Just For One Day goes down a different route. Rather than just recreate the famous Live Aid concert with a procession of soundalikes, it attempts to tell the story <em>behind</em> the concert. In doing so, it chops dozens of songs into thousands of pieces and lets the snippets segue seamlessly into the prose. It entwines the songs into each other beautifully. A supremely talented cast backed with a superb live band - it is guaranteed to have you screaming and cheering.</p>
1161
1162 <p>The central plot device is a <em>little</em> silly - a mother who went to the concert is chiding her teenage daughter about political activism. It is a bit mawkish and gets the show off to a stage-schooly start. Similarly, the daughter's righteous indignation fuels her interrogation of Saint Geldof which, again, becomes a bit preachy.</p>
1163
1164 <p>But that's the nature of Live Aid. It <em>is</em> preachy. And for all the arguments about whether it was the <strong>right</strong> thing to do - at least it did <strong>something</strong>. The show doesn't gloss over some the problems - and problem personalities - behind the production. Nor does it shy away from the reality of the limits of the help provided. Albeit backed by joyous music.</p>
1165
1166 <p>I felt that it pulls its punches a little bit. Rather than showing any footage from the Ethiopian famine, it <a href="https://www.independent.co.uk/news/uk/bob-geldof-belfast-icc-ethiopia-barack-obama-b2423253.html">recycles a speech Geldof gave a few years ago</a>.</p>
1167
1168 <p>Nevertheless, it is a powerful and moving spectacle.</p>
1169
1170 <p>Oh, and there's a rap battle between Bob Geldof and Mrs Thatcher.</p>
1171
1172 <p>Tickets start at £20. The music is so loud, and the staging so expressive, that you'll get a decent view from the cheap seats.</p>
1173
1174 <p>Far better than the average jukebox musical.</p>
1175
1176 <h2 id="pre-show-and-post-show"><a href="https://shkspr.mobi/blog/2025/06/theatre-review-just-for-one-day/#pre-show-and-post-show" class="heading-link">Pre-show and Post-show</a></h2>
1177
1178 <p>As regular readers of <a href="https://shkspr.mobi/blog/tag/theatre-review/">my theatre reviews</a> know, I'm obsessed with how theatres treat their patrons.</p>
1179
1180 <p>Bag searches were conducted quickly, and they were happy to let me bring in a small plastic bottle of water. The Shaftesbury has spacious corridors and bars. There are plenty of toilets which - in a shocking departure from West End tradition - are well maintained.</p>
1181
1182 <p>There's a little bit of set dressing inside the theatre to allow the audience to take selfies with famous backdrops. That's cute - but it might have been nice if they'd added a few more, or even put up original posters, press clippings, etc.</p>
1183
1184 <p>As we exited the theatre we were handed a commemorative ticket! What a swell idea! I thought it contained a QR code to donate to <a href="https://www.bandaidtrust.co.uk/">the Band Aid Charitable Trust</a> or find out more about their projects. Instead it's a coupon for £20 off your next visit. That feels like a bit of a missed opportunity.</p>
1185 </body></html>]]></content>
1186
1187 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/theatre-review-just-for-one-day/#comments" thr:count="0" />
1188 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/theatre-review-just-for-one-day/feed/atom/" thr:count="0" />
1189 <thr:total>0</thr:total>
1190 </entry>
1191 <entry>
1192 <author>
1193 <name>@edent</name>
1194 </author>
1195
1196 <title type="html"><![CDATA[Reading NFC Passport Chips in Linux]]></title>
1197 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/" />
1198
1199 <id>https://shkspr.mobi/blog/?p=61546</id>
1200 <updated>2025-06-24T12:12:53Z</updated>
1201 <published>2025-06-24T11:34:49Z</published>
1202 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="CyberSecurity" /><category scheme="https://shkspr.mobi/blog" term="hacking" /><category scheme="https://shkspr.mobi/blog" term="linux" /><category scheme="https://shkspr.mobi/blog" term="nfc" /><category scheme="https://shkspr.mobi/blog" term="rfid" />
1203 <summary type="html"><![CDATA[For boring and totally not nefarious reasons, I want to read all the data contained in my passport's NFC chip using Linux. After a long and annoying search, I settled on roeften's pypassport. I can now read all the passport information, including biometrics. Table of ContentsBackgroundRecreating the MRZPython code to generate an MRZCan you read a cancelled passport?Cryptography and other…]]></summary>
1204
1205 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/"><![CDATA[
1206 <html><head></head><body><p>For boring and totally not nefarious reasons, I want to read all the data contained in my passport's NFC chip using Linux. After a long and annoying search, I settled on <a href="https://github.com/roeften/pypassport">roeften's pypassport</a>.</p>
1207
1208 <p>I can now read all the passport information, including biometrics.</p>
1209
1210 <p></p><nav id="toc"><menu id="toc-start"><li id="toc-title"><h2 id="table-of-contents"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#table-of-contents" class="heading-link">Table of Contents</a></h2><menu><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#background">Background</a><menu><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#recreating-the-mrz">Recreating the MRZ</a><menu><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#python-code-to-generate-an-mrz">Python code to generate an MRZ</a></li></menu></li></menu></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#can-you-read-a-cancelled-passport">Can you read a cancelled passport?</a></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#cryptography-and-other-security">Cryptography and other security</a></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#can-you-brute-force-a-passport">Can you brute-force a passport?</a><menu><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#is-it-worth-brute-forcing-a-password">Is it worth brute-forcing a password?</a></li></menu></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#installing">Installing</a></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#getting-structured-data">Getting structured data</a><menu><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#saving-the-image">Saving the image</a></li></menu></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#what-didnt-work">What didn't work</a><menu><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#mrtdreader">mrtdreader</a></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#jean-francois-houzards-and-olivier-rogers-pypassport">Jean-Francois Houzard's and Olivier Roger's pyPassport</a></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#beaujeans-pypassport">beaujean's pyPassport</a></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#d-logic">d-Logic</a></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#android-reader">Android reader</a></li></menu></li><li><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#is-it-worth-it">Is it worth it?</a></li></menu></li></menu></nav><p></p>
1211
1212 <h2 id="background"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#background" class="heading-link">Background</a></h2>
1213
1214 <p>The NFC chip in a passport is protected by a password. The password is printed on the inside of the physical passport. As well as needing to be physically close to the passport for NFC to work<sup id="fnref:long"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fn:long" class="footnote-ref" title="There are some commercially available long range readers - up to 15cm! I've no doubt some clever engineer has made a some high-powered radio device which can read things from a mile away using a…" role="doc-noteref">0</a></sup>, you also need to be able to see the password. The password is printed in the "Machine Readable Zone" (MRZ) - which is why some border guards will swipe your passport through a reader before scanning the chip; they need the password and don't want to type it in.</p>
1215
1216 <p>I had a small problem though. I'm using my old passport<sup id="fnref:old"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fn:old" class="footnote-ref" title="I'm not dumb enough to do this stuff on a live passport!" role="doc-noteref">1</a></sup> which <a href="https://www.gov.uk/government/publications/cancellation-of-passports/cancelling-british-passports-accessible#cancelling-epassport-version-2">has been cancelled</a>. Cancelling isn't just about revoking the document. It is also physically altered:</p>
1217
1218 <blockquote><p>Cut off the bottom left hand corner of the personal details page, making sure you cut the MRZ on the corner opposite the photo.</p></blockquote>
1219
1220 <p>So a chunk of the MRZ is missing! Oh no! Whatever can we do!?</p>
1221
1222 <h3 id="recreating-the-mrz"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#recreating-the-mrz" class="heading-link">Recreating the MRZ</a></h3>
1223
1224 <p>The password is made up of three pieces of data:</p>
1225
1226 <ol>
1227 <li>Passport Number (Letters and Numbers)</li>
1228 <li>Date of Birth (YYMMDD)</li>
1229 <li>Expiry Date (YYMMDD)</li>
1230 </ol>
1231
1232 <p>Each piece <em>also</em> has a checksum. This calculation is defined in Appendix A to <a href="https://www.icao.int/publications/Documents/9303_p3_cons_en.pdf">Part 3 of Document 9303</a>.</p>
1233
1234 <p>Oh, and there's a checksum for the entire string. It's this final checksum which is cut off when the passport cover is snipped.</p>
1235
1236 <p>The final password is: <code>Number Number-checksum DOB DOB-checksum Expiry Expiry-checkum checksum-of-previous-digits</code></p>
1237
1238 <h4 id="python-code-to-generate-an-mrz"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#python-code-to-generate-an-mrz" class="heading-link">Python code to generate an MRZ</a></h4>
1239
1240 <p>If you know the passport number, date of birth, and expiry date, you can generate your own Machine Readable Zone - this acts as the password for the NFC chip.</p>
1241
1242 <pre><code class="language-python">def calculateChecksum( value ):
1243 weighting = [7,3,1]
1244 characterWeight = {
1245 '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7,
1246 '8': 8, '9': 9, '<': 0, 'A':10, 'B':11, 'C':12, 'D':13, 'E':14,
1247 'F':15, 'G':16, 'H':17, 'I':18, 'J':19, 'K':20, 'L':21, 'M':22,
1248 'N':23, 'O':24, 'P':25, 'Q':26, 'R':27, 'S':28, 'T':29, 'U':30,
1249 'V':31, 'W':32, 'X':33, 'Y':34, 'Z':35
1250 }
1251 counter = 0
1252 result = 0
1253 for x in value:
1254 result += characterWeight[str(x)] * weighting[counter%3]
1255 counter += 1
1256 return str(result%10)
1257
1258 def calculateMRZ( passportNumber, DOB, expiry ):
1259 """
1260 DOB and expiry are formatted as YYMMDD
1261 """
1262 passportCheck = calculateChecksum( passportNumber )
1263 DOBCheck = calculateChecksum( DOB )
1264 expiryCheck = calculateChecksum( expiry )
1265 mrzNumber = passportNumber + passportCheck + DOB + DOBCheck + expiry + expiryCheck
1266 mrzCheck = calculateChecksum( mrzNumber ).zfill(2)
1267 mrz = passportNumber + passportCheck + "XXX" + DOB + DOBCheck + "X" + expiry + expiryCheck + "<<<<<<<<<<<<<<" + mrzCheck
1268 return mrz
1269
1270 print( calculateMRZ("123456789", "841213", "220229") )
1271 </code></pre>
1272
1273 <h2 id="can-you-read-a-cancelled-passport"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#can-you-read-a-cancelled-passport" class="heading-link">Can you read a cancelled passport?</a></h2>
1274
1275 <p>I would have thought that cutting the cover of the passport would destroy the antenna inside it. But, going back to <a href="https://www.gov.uk/government/publications/cancellation-of-passports/cancelling-british-passports-accessible#cancelling-epassport-version-2">the UK guidance</a>:</p>
1276
1277 <blockquote><p>You must not cut the back cover on the ePassport</p></blockquote>
1278
1279 <p>Ah! That's where the NFC chip is. I presume this is so that cancelled passports can still be verified for authenticity.</p>
1280
1281 <h2 id="cryptography-and-other-security"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#cryptography-and-other-security" class="heading-link">Cryptography and other security</a></h2>
1282
1283 <p>The security is, thankfully, all fairly standard Public Key Cryptography - <a href="https://www.icao.int/publications/Documents/9303_p11_cons_en.pdf">9303 part 11</a> explains it in <em>excruciating</em> levels of detail.</p>
1284
1285 <p>One thing I found curious - because the chip has no timer, it cannot know how often it is being read. You could bombard it with thousands of password attempts and not get locked out. Indeed, the specification says:</p>
1286
1287 <blockquote><p>the success probability of the attacker is given by the time the attacker has access to the IC, the duration of a single attempt to guess the password, and the entropy of the passport.</p></blockquote>
1288
1289 <h2 id="can-you-brute-force-a-passport"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#can-you-brute-force-a-passport" class="heading-link">Can you brute-force a passport?</a></h2>
1290
1291 <p>Wellllll… maybeeeee…?</p>
1292
1293 <p>Passports are generally valid for only 10 years. So that's 36,525 possible expiry dates.</p>
1294
1295 <p>Passport holders are generally under 100 years old. So that's 3,652,500 possible dates of birth.</p>
1296
1297 <p>That's already 133,407,562,500 attempts - and we haven't even got on to the 1E24 possible passport numbers!</p>
1298
1299 <p>In my experiments, sending an incorrect but valid MRZ results in the chip returning "Security status not satisfied (0x6982)" in a very short space of time. Usually less than a second.</p>
1300
1301 <p>But sending that incorrect attempt seemed to introduce a delay in the next response - by a few seconds. Sending the correct MRZ seemed to reset this and let the chip be read instantly.</p>
1302
1303 <p>So, if you knew the target's passport number and birthday, brute forcing the expiry date would take a couple of days. Not instant, but not impossible.</p>
1304
1305 <p>Most <a href="https://www.nxp.com/docs/en/data-sheet/NTAG213_215_216.pdf">commercial NFC chips support 100,000 writes</a> with no limit for the number of reads. Some also have a 24 bit read counter which increments after every read attempt. After 16 million reads, the counter doesn't increment. It <em>could</em> be possible for a chip to self-destruct after a specific number of reads - but I've no evidence that passport chips do that.</p>
1306
1307 <h3 id="is-it-worth-brute-forcing-a-password"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#is-it-worth-brute-forcing-a-password" class="heading-link">Is it <em>worth</em> brute-forcing a password?</a></h3>
1308
1309 <p>If you were to brute-force the MRZ, you would discover the passport-holder's date of birth. You would also get:</p>
1310
1311 <ul>
1312 <li>A digital copy of their photo,</li>
1313 <li>Their full name,</li>
1314 <li>Their sex<sup id="fnref:sex"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fn:sex" class="footnote-ref" title="Sex is complicated. But ICAO allow for "F for female, M for male, or X for unspecified"." role="doc-noteref">2</a></sup>,</li>
1315 <li>The country which issued their passport, and</li>
1316 <li>Their nationality.</li>
1317 </ul>
1318
1319 <p>All of that is something which you can see from looking at the passport. So there's little value in attempting to read it electronically.</p>
1320
1321 <h2 id="installing"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#installing" class="heading-link">Installing</a></h2>
1322
1323 <p>As mentioned, I'm using <a href="https://github.com/roeften/pypassport">https://github.com/roeften/pypassport</a></p>
1324
1325 <p>The only library I needed to install was <a href="https://pypi.org/project/pyasn1/">pyasn1</a> using <code>pip3 install pyasn1</code> - your setup may vary.</p>
1326
1327 <p>Download PyPassport. In the same directory, you can create a test Python file to see if the passport can be read. Here's what it needs to contain:</p>
1328
1329 <pre><code class="language-python">from pypassport import epassport, reader
1330
1331 # Replace this MRZ with the one from your passport
1332 MRZ = "1234567897XXX8412139X2202299<<<<<<<<<<<<<<04"
1333
1334 def trace(name, msg):
1335 if name == "EPassport":
1336 print(name + ": " + msg)
1337
1338 r = reader.ReaderManager().waitForCard()
1339
1340 ep = epassport.EPassport(r, MRZ)
1341 ep.register(trace)
1342 ep.readPassport()
1343 </code></pre>
1344
1345 <p>Plug in your NFC reader, place your passport on it, run the above code. If it works, it will spit out a lot of debug information, including all the data it can find on the passport.</p>
1346
1347 <h2 id="getting-structured-data"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#getting-structured-data" class="heading-link">Getting structured data</a></h2>
1348
1349 <p>The structure of the passport data is a little convoluted. <a href="https://www.icao.int/publications/Documents/9303_p10_cons_en.pdf">The specification</a> puts data into different "Data Groups" - each with its own ID.</p>
1350
1351 <p>By running:</p>
1352
1353 <pre><code class="language-python">ep.keys()
1354 </code></pre>
1355
1356 <p>You can see which Data Groups are available. In my case, <code>['60', '61', '75', '77']</code></p>
1357
1358 <ul>
1359 <li><code>60</code> is the common area which contains some metadata. Nothing interesting there.</li>
1360 <li><code>61</code> is DG1 - the full MRZ. This contains the holder's name, sex, nationality, etc.</li>
1361 <li><code>77</code> is the Document Security Object - this was empty for me.</li>
1362 <li><code>75</code> is DG2 to DG4 Biometric Templates - this contains the image and other metadata.</li>
1363 </ul>
1364
1365 <p>Dumping the biometrics - <code>print( ep["75"] )</code> - gives these interesting pieces of metadata:</p>
1366
1367 <pre><code class="language-_">'83': '20190311201345',
1368 'meta': { 'Expression': 'Unspecified',
1369 'EyeColour' : 'Unspecified',
1370 'FaceImageBlockLength': 19286,
1371 'FaceImageType': 'Basic',
1372 'FeatureMask': '000000',
1373 'FeaturePoint': {0: {'FeaturePointCode': 'C1',
1374 'FeatureType': '01',
1375 'HorizontalPosition': 249,
1376 'Reserved': '0000',
1377 'VerticalPosition': 216},
1378 1: {'FeaturePointCode': 'C2',
1379 'FeatureType': '01',
1380 'HorizontalPosition': 141,
1381 'Reserved': '0000',
1382 'VerticalPosition': 214}},
1383 'Features': {},
1384 'Gender': 'Unspecified',
1385 'HairColour': 'Unspecified',
1386 'ImageColourSpace': 'RGB24',
1387 'ImageDataType': 'JPEG',
1388 'ImageDeviceType': 0,
1389 'ImageHeight': 481,
1390 'ImageQuality': 'Unspecified',
1391 'ImageSourceType': 'Static Scan',
1392 'ImageWidth': 385,
1393 'LengthOfRecord': 19300,
1394 'NumberOfFacialImages': 1,
1395 'NumberOfFeaturePoint': 2,
1396 'PoseAngle': '0600B5',
1397 'PoseAngleUncertainty': '000000',
1398 'VersionNumber': b'010'
1399 }
1400 </code></pre>
1401
1402 <p>If I understand <a href="https://www.icao.int/security/mrtd/siteassets/pages/technical-reports/tr%20-%20rf%20and%20protocol%20testing%20part%204%20v2.10.pdf">the testing document</a> - the "Feature Points" are the middle of the eyes. Interesting to see that gender (not sex!) and hair colour are also able to be recorded. The "PoseAngle" represents the <a href="https://www.icao.int/Security/FAL/TRIP/Documents/TR%20-%20Portrait%20Quality%20v1.0.pdf">pitch, yaw, and roll</a> of the face.</p>
1403
1404 <h3 id="saving-the-image"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#saving-the-image" class="heading-link">Saving the image</a></h3>
1405
1406 <p>Passport images are saved either with JPEG or with <a href="https://www.icao.int/Security/FAL/TRIP/Documents/TR%20-%20Portrait%20Quality%20v1.0.pdf">JPEG2000 encoding</a>. Given the extremely limited memory available photos are small and highly compressed. Mine was a mere 19KB.</p>
1407
1408 <p>To save the image, grab the bytes and plonk them onto disk:</p>
1409
1410 <pre><code class="language-python">photo = ep["75"]["A1"]["5F2E"]
1411 with open( "photo.jpg", "wb" ) as f:
1412 f.write( photo )
1413 </code></pre>
1414
1415 <p>As expected, the "FeaturePoints" co-ordinates corresponded roughly to the centre of my eyes. Nifty!</p>
1416
1417 <h2 id="what-didnt-work"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#what-didnt-work" class="heading-link">What didn't work</a></h2>
1418
1419 <p>I tried a few different tools. Listed here so you don't make the same mistakes as me!</p>
1420
1421 <h3 id="mrtdreader"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#mrtdreader" class="heading-link">mrtdreader</a></h3>
1422
1423 <p>The venerable <a href="https://github.com/rubund/mrtdreader">mrtdreader</a>. My NFC device beeped, then mrtdreader said "No NFC device found."</p>
1424
1425 <p>I think this is because <a href="https://github.com/nfc-tools/libnfc/issues/719">NFC Tools haven't been updated in ages</a>.</p>
1426
1427 <h3 id="jean-francois-houzards-and-olivier-rogers-pypassport"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#jean-francois-houzards-and-olivier-rogers-pypassport" class="heading-link">Jean-Francois Houzard's and Olivier Roger's pyPassport</a></h3>
1428
1429 <p>I looked at <a href="https://code.google.com/archive/p/pypassport/">pyPassport</a> but it is only available for Python 2.</p>
1430
1431 <h3 id="beaujeans-pypassport"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#beaujeans-pypassport" class="heading-link">beaujean's pyPassport</a></h3>
1432
1433 <p>This <a href="https://github.com/beaujeant/pypassport">pypassport</a> only checks if a passport is resistant to specific security vulnerabilities.</p>
1434
1435 <h3 id="d-logic"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#d-logic" class="heading-link">d-Logic</a></h3>
1436
1437 <p><a href="https://www.d-logic.com/nfc-rfid-reader-sdk/software/epassport-reading/">Digital Logic's ePassport software</a> only works with their hardware readers.</p>
1438
1439 <h3 id="android-reader"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#android-reader" class="heading-link">Android reader</a></h3>
1440
1441 <p><a href="https://github.com/tananaev/passport-reader">tananaev's passport-reader</a> - works perfectly on Android. So I knew my passport chip was readable - but the app won't run on Linux.</p>
1442
1443 <h2 id="is-it-worth-it"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#is-it-worth-it" class="heading-link">Is it worth it?</a></h2>
1444
1445 <p>Yeah, I reckon so! Realistically, you aren't going to be able to crack the MRZ to read someone's passport. But if you need to gather personal information<sup id="fnref:gdpr"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fn:gdpr" class="footnote-ref" title="Under the auspices of GDPR, of course!" role="doc-noteref">3</a></sup>, it's perfectly possible to do so quickly from a passport.</p>
1446
1447 <p>The MRZ is a <em>Machine Readable</em> Zone - so it is fairly simple to OCR the text and then pass that to your NFC reader.</p>
1448
1449 <p>And even if the MRZ is gone, you can reconstruct it from the data printed on the passport.</p>
1450
1451 <p>Of course, this won't be able to detect fraudulent passports. It doesn't check against a database to see if it has been revoked<sup id="fnref:interpol"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fn:interpol" class="footnote-ref" title="Nor does it check if the holder is on some Interpol list." role="doc-noteref">4</a></sup>. I don't think it will detect any cryptographic anomalies.</p>
1452
1453 <p>But if you just want to see what's on your travel documents, it works perfectly.</p>
1454
1455 <div class="footnotes" role="doc-endnotes">
1456 <hr>
1457 <ol start="0">
1458
1459 <li id="fn:long" role="doc-endnote">
1460 <p>There are some <a href="https://www.shopnfc.com/en/nfc-readers-writers/300-nfc-xl-reader-long-range-hf-reader.html">commercially available long range readers</a> - up to 15cm! I've no doubt some clever engineer has made a some high-powered radio device which can read things from a mile away using a <a href="https://www.makeuseof.com/tag/how-to-make-a-wifi-antenna-out-of-a-pringles-can-nb/">Pringle's tube</a>. Of note, the <a href="https://www.icao.int/publications/Documents/9303_p11_cons_en.pdf">ICAO guidance</a> says:</p>
1461
1462 <blockquote><p>the unencrypted communication between a contactless IC and a reader can be eavesdropped within a distance of several metres.</p></blockquote>
1463
1464 <p><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fnref:long" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1465 </li>
1466
1467 <li id="fn:old" role="doc-endnote">
1468 <p>I'm not dumb enough to do this stuff on a <em>live</em> passport! <a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fnref:old" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1469 </li>
1470
1471 <li id="fn:sex" role="doc-endnote">
1472 <p>Sex is complicated<sup id="fnref:giggle"><a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fn:giggle" class="footnote-ref" title="Stop giggling at the back!" role="doc-noteref">5</a></sup>. But ICAO allow for "<a href="https://www.icao.int/publications/Documents/9303_p4_cons_en.pdf">F for female, M for male, or X for unspecified</a>". <a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fnref:sex" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1473 </li>
1474
1475 <li id="fn:gdpr" role="doc-endnote">
1476 <p>Under the auspices of GDPR, of course! <a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fnref:gdpr" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1477 </li>
1478
1479 <li id="fn:interpol" role="doc-endnote">
1480 <p>Nor does it check if the holder is on some Interpol list. <a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fnref:interpol" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1481 </li>
1482
1483 <li id="fn:giggle" role="doc-endnote">
1484 <p>Stop giggling at the back! <a href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#fnref:giggle" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1485 </li>
1486
1487 </ol>
1488 </div>
1489 </body></html>]]></content>
1490
1491 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/#comments" thr:count="8" />
1492 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/reading-nfc-passport-chips-in-linux/feed/atom/" thr:count="8" />
1493 <thr:total>8</thr:total>
1494 </entry>
1495 <entry>
1496 <author>
1497 <name>@edent</name>
1498 </author>
1499
1500 <title type="html"><![CDATA[An annoying SVG animation bug in Chrome]]></title>
1501 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/" />
1502
1503 <id>https://shkspr.mobi/blog/?p=61537</id>
1504 <updated>2025-06-23T09:03:34Z</updated>
1505 <published>2025-06-23T11:34:12Z</published>
1506 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="bug" /><category scheme="https://shkspr.mobi/blog" term="chrome" /><category scheme="https://shkspr.mobi/blog" term="chromium" /><category scheme="https://shkspr.mobi/blog" term="svg" />
1507 <summary type="html"><![CDATA[Writing web standards is hard. You have to write a formal specification which is useful for machines, humans, and web developers. I recently stumbled across what I think is a little bug which might be caused by a misreading of the SVG Animation specification. Here you should see two overlapping circles gradually appear: If you're on Chrome, you…]]></summary>
1508
1509 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/"><![CDATA[
1510 <html><head></head><body><p>Writing web standards is hard<sup id="fnref:experience"><a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fn:experience" class="footnote-ref" title="I do have some experience in this matter." role="doc-noteref">0</a></sup>. You have to write a formal specification which is useful for machines, humans, and web developers<sup id="fnref:webdev"><a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fn:webdev" class="footnote-ref" title="Back in 2006, Catharine A. MacKinnon provokatively asked "Are Women Human?". Her argument (which I shall badly summarise) is that if women were human, then they'd be protected by universal human…" role="doc-noteref">1</a></sup>.</p>
1511
1512 <p>I recently stumbled across what I think is a little bug which <em>might</em> be caused by a misreading of <a href="https://svgwg.org/specs/animations/#KeyTimesAttribute">the SVG Animation specification</a>. Here you should see two overlapping circles gradually appear:</p>
1513
1514 <svg width="170" height="170" xmlns="http://www.w3.org/2000/svg">
1515 <path fill="#2c4169" d="M170 0H0v170h170z"></path>
1516 <circle r="45" cx="50" cy="50" fill="#e4da2e" opacity="0">
1517 <animate attributeName="opacity" begin="0s" dur="30s" values="0; 1;" keyTimes="0; 1" fill="freeze"></animate>
1518 </circle>
1519 <circle r="45" cx="80" cy="80" fill="red" opacity="0">
1520 <animate attributeName="opacity" begin="0s" dur="30s" values="0; 1;" keyTimes="0; 1;" fill="freeze"></animate>
1521 </circle>
1522 </svg>
1523
1524 <p>If you're on Chrome, you might only see one circle animate. Why? Bloody semicolons! The bane of every programmer's existence<sup id="fnref:eng"><a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fn:eng" class="footnote-ref" title="I imagine English literature students also find them confusing; everyone does." role="doc-noteref">2</a></sup>.</p>
1525
1526 <p>The <a href="https://svgwg.org/specs/animations/#KeyTimesAttribute">specification for SVG Animation</a> has this text for human readers:</p>
1527
1528 <blockquote><p><strong>keyTimes</strong></p>
1529
1530 <p>A semicolon-separated list of time values used to control the pacing of the animation. Each time in the list corresponds to a value in the ‘values’ attribute list, and defines when the value is used in the animation function.</p>
1531
1532 <p>[…]</p>
1533
1534 <p>If the last semicolon separator is followed by either just white space or no more characters, ignore both the separator and the trailing white space.</p></blockquote>
1535
1536 <p>To me, that isn't ambiguous. The text <code>keyTimes="0; 1;"</code> has a final semicolon with nothing after it. Therefore it should be ignored. Instead, Chrome throws an hissyfit and says <code>Error: <animate> attribute keyTimes: Invalid value, "0; 1;".</code></p>
1537
1538 <p>But maybe the humans who wrote the description were sloppy. There's also a machine-readable formal specification. It defines the acceptable sequence as being:</p>
1539
1540 <p><code><number> [; <number>]* ;?</code></p>
1541
1542 <p>This isn't quite Backus–Naur form<sup id="fnref:bnf"><a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fn:bnf" class="footnote-ref" title="Also the bane of programmers everywhere!" role="doc-noteref">3</a></sup>, but rather <a href="https://www.w3.org/TR/css-values/#value-defs">CSS Values</a>.</p>
1543
1544 <ul>
1545 <li>The <code><number></code> is a <a href="https://www.w3.org/TR/css-values/#component-types">component</a>.</li>
1546 <li>The <code>[</code> and <code>]</code> are <a href="https://www.w3.org/TR/css-values/#component-combinators">grouping combinators</a>.</li>
1547 <li>The <code>*</code> and <code>?</code> are <a href="https://www.w3.org/TR/css-values/#component-multipliers">component multipliers</a>
1548
1549 <ul>
1550 <li><code>*</code> "indicates that the preceding type, word, or group occurs zero or more times."</li>
1551 <li><code>?</code> "indicates that the preceding type, word, or group is optional (occurs zero or one times)."</li>
1552 </ul></li>
1553 <li>The <code>;</code> is just a semicolon<sup id="fnref:cig"><a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fn:cig" class="footnote-ref" title="Just like how sometimes a cigar is just a cigar." role="doc-noteref">4</a></sup>.</li>
1554 </ul>
1555
1556 <p>Reading the definition tells us that a valid value will be a number, followed by zero-or-more groups of "semicolon and another number" with an optional final semicolon.</p>
1557
1558 <p>So, based on my reading, I think Chrome is wrong to throw an error here. Both Firefox and Safari work with a trailing semicolon.</p>
1559
1560 <p>Accordingly, I've <a href="https://issues.chromium.org/issues/427020732">raised a bug with the Chromium team</a>. If you think I have erred in this matter, please let me know.</p>
1561
1562 <div class="footnotes" role="doc-endnotes">
1563 <hr>
1564 <ol start="0">
1565
1566 <li id="fn:experience" role="doc-endnote">
1567 <p>I do have <a href="https://www.w3.org/TR/2018/WD-html53-20180426/">some experience in this matter</a>. <a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fnref:experience" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1568 </li>
1569
1570 <li id="fn:webdev" role="doc-endnote">
1571 <p>Back in 2006, Catharine A. MacKinnon provokatively asked "<a href="https://doi.org/10.2307/j.ctvjnrvck">Are Women Human?</a>". Her argument (which I shall badly summarise) is that if women <em>were</em> human, then they'd be protected by universal human rights. Given the state of the world then (and now) it is hard to argue that women receive as great a level of attention as the <a href="https://www.the-tls.com/politics-society/rights-equality/default-male">default male</a>. I don't intend to trivialise MacKinnon's work - but I do find it interesting that developers are often treated separately from other humans. <a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fnref:webdev" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1572 </li>
1573
1574 <li id="fn:eng" role="doc-endnote">
1575 <p>I imagine English literature students also find them confusing; everyone does. <a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fnref:eng" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1576 </li>
1577
1578 <li id="fn:bnf" role="doc-endnote">
1579 <p>Also the bane of programmers everywhere! <a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fnref:bnf" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1580 </li>
1581
1582 <li id="fn:cig" role="doc-endnote">
1583 <p>Just like how <a href="https://quoteinvestigator.com/2011/08/12/just-a-cigar/">sometimes a cigar is just a cigar</a>. <a href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#fnref:cig" class="footnote-backref" role="doc-backlink"><img src="https://s.w.org/images/core/emoji/15.1.0/72x72/21a9.png" alt="↩" class="wp-smiley" style="height: 1em; max-height: 1em;" />︎</a></p>
1584 </li>
1585
1586 </ol>
1587 </div>
1588 </body></html>]]></content>
1589
1590 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/#comments" thr:count="1" />
1591 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/an-annoying-svg-animation-bug-in-chrome/feed/atom/" thr:count="1" />
1592 <thr:total>1</thr:total>
1593 </entry>
1594 <entry>
1595 <author>
1596 <name>@edent</name>
1597 </author>
1598
1599 <title type="html"><![CDATA[Theatre Review: Operation Mincemeat ★★★★☆]]></title>
1600 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/theatre-review-operation-mincemeat/" />
1601
1602 <id>https://shkspr.mobi/blog/?p=61507</id>
1603 <updated>2025-06-22T09:14:43Z</updated>
1604 <published>2025-06-22T11:34:01Z</published>
1605 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Theatre Review" />
1606 <summary type="html"><![CDATA[Everyone I know told me to go and see this show. I resisted as long as possible but managed to score cheap last-minute tickets via a friend. I wish I hadn't waited so long! If you're unaware of the book (or the film. Or the novelisation of the film. Or the Twitter thread. Or the inaccurate tumblr retelling.) the story involves a dastardly British plan to use a corpse to fool the Nazi menace…]]></summary>
1607
1608 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/theatre-review-operation-mincemeat/"><![CDATA[
1609 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/Operation_Mincemeat-1-400-400-100-nocrop.jpeg" alt="Logo for Operation Mincemeat - a black scribble on a yellow background." width="200" height="200" class="alignleft size-full wp-image-61508"> Everyone I know told me to go and see this show. I resisted as long as possible but managed to score cheap last-minute tickets via a friend. I wish I hadn't waited so long!</p>
1610
1611 <p>If you're unaware of the book (or the film. Or the novelisation of the film. Or the Twitter thread. Or the inaccurate tumblr retelling.) the story involves a dastardly British plan to use a corpse to fool the Nazi menace into diverting their troops.</p>
1612
1613 <p>So, naturally, this is a glitzy West End Musical. And, as befitting a story with a hundred different characters, there are five cast members playing everyone. Obviously, it is <em>very</em> silly.</p>
1614
1615 <p>I can't lie - I found the start of the first act a bit underwhelming. It feels derivative of every other musical I've seen; like a British "Hamilton" without the budget. But as it wore on, something magical happened. The songs become interesting, the choreography leaps alive, and the cast started playing off the audience’s energy.</p>
1616
1617 <p>The second act has the strongest opening I've seen in a good long while. It builds to a terrific conclusion - with just the right amount of joy and melancholy.</p>
1618
1619 <p>Naturally, the cast are superb. It's exhausting watching them quick-change and shimmy across the stage. They are a beautifully formed ensemble. I usually don't like seeing shows multiple times, but given the frequent cast changes I find myself curious about how the various permutations work.</p>
1620
1621 <p>It is an excellent and kinetic work of theatre. It revels in its daftness and knows exactly when to tug your heartstrings.</p>
1622
1623 <h2 id="pre-show"><a href="https://shkspr.mobi/blog/2025/06/theatre-review-operation-mincemeat/#pre-show" class="heading-link">Pre-Show</a></h2>
1624
1625 <p>Regular readers know how much I love discussing the pre-show elements. Mincemeat isn't as bad as most, but still treats the paying audience with the contempt London venues are known for.</p>
1626
1627 <p>The theatre is cramped, with a packed bar, and inadequate toilet facilities. The corridors are decorated with photos of current cast members, which is nice. There's also a pre-show trivia quiz which, while fun, is only half-a-dozen questions - essentially a thinly veiled attempt to get you onto a mailing list.</p>
1628
1629 <p>The cost of the programme is exorbitant - an advert filled brochure with the same information as can be found on the website.</p>
1630
1631 <p>On the plus side, the stall seats are spacious and there's a bar to one side (if you can afford it).</p>
1632
1633 <p>A single "cheap" ticket usually costs about 3-months of Netflix. Full price tickets are a monocle-popping 7-months of Netflix! At that price I'd expect a free souvenir programme and a complimentary ice-cream. And possibly a foot-massage.</p>
1634
1635 <p>The <a href="https://operationmincemeat.com/tickets/">ticket lottery</a> reduces prices to a shade under 2-months of Netflix.</p>
1636
1637 <p>There's nothing like seeing live theatre performed by a hyper-talented cast. Theatres need to understand that home entertainment is ubiquitous, cheap, <strong>and comfortable</strong>. If I can't pause your show to go for a wee, you'd better make sure you have enough loos for everyone at the interval.</p>
1638 </body></html>]]></content>
1639
1640 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/theatre-review-operation-mincemeat/#comments" thr:count="0" />
1641 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/theatre-review-operation-mincemeat/feed/atom/" thr:count="0" />
1642 <thr:total>0</thr:total>
1643 </entry>
1644 <entry>
1645 <author>
1646 <name>@edent</name>
1647 </author>
1648
1649 <title type="html"><![CDATA[Book Review: Venomous Lumpsucker by Ned Beauman ★★★★★]]></title>
1650 <link rel="alternate" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-venomous-lumpsucker-by-ned-beauman/" />
1651
1652 <id>https://shkspr.mobi/blog/?p=61183</id>
1653 <updated>2025-06-13T09:16:16Z</updated>
1654 <published>2025-06-21T11:34:56Z</published>
1655 <category scheme="https://shkspr.mobi/blog" term="/etc/" /><category scheme="https://shkspr.mobi/blog" term="Book Review" /><category scheme="https://shkspr.mobi/blog" term="satire" /><category scheme="https://shkspr.mobi/blog" term="Sci Fi" />
1656 <summary type="html"><![CDATA[No book has the right to be this good. It's the sort of howling sci-fi satire that Ben Elton used to excel at - a novel set five minutes in the future with a eye firmly on today's problems. The plot is delightful - what if carbon credits extinction credits were the new capitalist plaything? What second, third, and forth order effects would that have on the world? The worldbuilding is sublime -…]]></summary>
1657
1658 <content type="html" xml:base="https://shkspr.mobi/blog/2025/06/book-review-venomous-lumpsucker-by-ned-beauman/"><![CDATA[
1659 <html><head></head><body><p><img src="https://shkspr.mobi/blog/wp-content/uploads/2025/06/hbg-title-venomous-lumpsucker-4-1.webp" alt="Book cover with fish." width="200" class="alignleft size-full wp-image-61184"> No book has the right to be this good. It's the sort of howling sci-fi satire that Ben Elton used to excel at - a novel set five minutes in the future with a eye firmly on today's problems.</p>
1660
1661 <p>The plot is delightful - what if <del>carbon credits</del> extinction credits were the new capitalist plaything? What second, third, and forth order effects would that have on the world? The worldbuilding is sublime - with an prescient look at the evolution of DRM, Smart Contracts, AI assistants, and targetted assassinations.</p>
1662
1663 <p>The characters are perfectly fleshed out and gradually reveal their motivations and insecurities:</p>
1664
1665 <blockquote><p>one big thing about the socially normal was that they loved their social norms. Whereas Resaint couldn’t stand the politics, the niceties, the meetings where she had to spangle her expression and tone of voice with false enthusiasm just so people didn’t think she was a bitch.</p></blockquote>
1666
1667 <p>There is a <em>slight</em> tendency towards Socratic dialogue as a means of exposition. The satire itself isn't exactly subtle - but when it has this many twists and turns I can forgive it for laying it on a bit thick.</p>
1668
1669 <p>The ending(s) genuinely shocked me.</p>
1670 </body></html>]]></content>
1671
1672 <link rel="replies" type="text/html" href="https://shkspr.mobi/blog/2025/06/book-review-venomous-lumpsucker-by-ned-beauman/#comments" thr:count="2" />
1673 <link rel="replies" type="application/atom+xml" href="https://shkspr.mobi/blog/2025/06/book-review-venomous-lumpsucker-by-ned-beauman/feed/atom/" thr:count="2" />
1674 <thr:total>2</thr:total>
1675 </entry>
1676 </feed>