<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/styles.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title> Daniel Reisch</title><description>A blog by Daniel Reisch</description><link>https://djreisch.com/</link><item><title>Creating an Apple/Android Wallet Pass for 24 Hour Fitness Memberships</title><link>https://djreisch.com/blog/24hr-qr/</link><guid isPermaLink="true">https://djreisch.com/blog/24hr-qr/</guid><description>The steps I used to reverse engineer the in-app QR code and a guide on how to add it yourself to Apple/Google Wallets.</description><pubDate>Sat, 25 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;24 Hour Fitness has converted their check-in method to time-based QR codes generated by their app &lt;strong&gt;24GO&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This sucks. The app is not very optimized, sucks down battery, and takes almost 200MB of space. The app blocks screenshots of the QR code &lt;em&gt;and&lt;/em&gt; the code changes every 5 minutes. However, there are some flaws in their verification logic that we can use to convert this time-based QR code to a static one that can be added to Apple or Android Wallets without the need for dynamic background services or push updates!&lt;/p&gt;
&lt;h2&gt;Getting the QR Data&lt;/h2&gt;
&lt;p&gt;Since the app prevents you from screen-shotting (at least on iOS) you&apos;ll have to use another camera to scan the QR code to get the JSON data. After you scan it, you should get something like this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{&quot;TP&quot;:&quot;X&quot;,&quot;OS&quot;:&quot;X&quot;,&quot;DT&quot;:9999999999999,&quot;DI&quot;:&quot;XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX&quot;,&quot;AP&quot;:&quot;X.XX.X&quot;,&quot;MB&quot;:&quot;MBRXXXXXXXX&quot;,&quot;SR&quot;:&quot;24GO&quot;}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Values have been replaced to avoid leaking personal info. From what I can glean, these are the definitions of each value:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;TP: Not sure what this indiacates.&lt;/li&gt;
&lt;li&gt;OS: This is the operating system, on my iPhone the value is iOS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DT&lt;/strong&gt;: The DateTime value in &lt;a href=&quot;https://en.wikipedia.org/wiki/Unix_time&quot;&gt;Unix Epoch time&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;DI: This appears to be the device identifier and is unique to the phone&lt;/li&gt;
&lt;li&gt;AP: This indicates the app version&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;MB&lt;/strong&gt;: This is your 24 Hour Fitness Member Number, unique to you&lt;/li&gt;
&lt;li&gt;SR: Indicates the scan source, it seems in all cases the value is 24GO, the app.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Circumventing the Time-Based Aspect&lt;/h2&gt;
&lt;p&gt;Generally these types of QR codes rely on a salted dynamic value, even if that&apos;s just a salted DateTime value. That is not the case here, which means as long as we regenerate the JSON string as a QR code with the current time every 5 minutes we should be fine.&lt;/p&gt;
&lt;p&gt;However it gets even better. During some field testing I discovered that the check-in system only checks if the DT value is older than the limit, not if it&apos;s in the future.&lt;/p&gt;
&lt;p&gt;This means we can set the DT value to something in the future and it passes the time validation check. I haven&apos;t found a limit to the system, so technically you can set the time to however far you want in the future (i.e. Jan 1 2077), but I would keep it within reason and only add a year or two.&lt;/p&gt;
&lt;h2&gt;The Steps&lt;/h2&gt;
&lt;p&gt;Take your original DT value and add 31557600000 to it, which is the number of seconds in 1 year (with millisecond precision). If you want to do a different time you can use a Unix time calculator like &lt;a href=&quot;https://www.unixtimestamp.com/&quot;&gt;UnixTimestamp&lt;/a&gt; to do it for you.&lt;/p&gt;
&lt;p&gt;Slap your modified Unix Epoch time back into the JSON object and convert it to a QR code. There are lots of sites you can use for this, like &lt;a href=&quot;https://smalldev.tools/qr-code-generator-online&quot;&gt;SmallDevTools&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Wallet Pass generators like &lt;a href=&quot;https://app.addpass.io/generator&quot;&gt;AddPass.io&lt;/a&gt; can generate the QR code for you. You paste the JSON text into the QR code generation box, and can even input a geolocation for the wallet to automatically open up to.&lt;/p&gt;
</content:encoded></item></channel></rss>