The third iteration of Doug Bolden's various thoughts and musings.

Tag: Python

Inline Substitution Ciphers to Play with Semi-Hidden Text

jLh 903mO moh0 m3 S6 SnE 0so Vhshn0Sh 3SnmsV3 6Y ShFS SL0S 0nh 903mO0MME ‘Lmoohs ms QM0ms 3mSh’ (C2r!) 9tS 0M36 Vhshn0MME nhO6Vsmd09Mh 03 LtU0s-BnmSShs ShFS 9E nhS0msmsV UtOL 6Y SLh QtsOSt0Sm6s, BLmSh3Q0Oh, 0so 6SLhn hMhUhsS3. jLm3 B6tMo hs09Mh Uh, Y6n ms3S0sOh, S6 BnmSh ShFS SL0S O6sS0msho 3Q6mMhn3 6n L0o 6SLhn 03QhOS3 s6S msShsoho S6 9h nh0o 9E jLh 7MV6nmSLU BLmMh 3tnn6tsoho 9E ShFS SL0S m3 QhnYhOSME LtU0s- 0so U0OLmsh-nh0o09Mh. a O6tMo 30E ‘J6t = Q66 Q66 Lh0o’ BmSL6tS SL0S 9hmsV msohFho. uE NhhQmsV mS 0 36UhBL0S 3mUQMh 3t93SmStSm6s OEQLhn, SLm3 Uh0s3 SL0S mS h03E Y6n Qh6QMh S6 Sn0s3M0Sh h1hs BmSL6tS 0sE 3OnmQS 0so 0MM6B3 mS S6 9h nhM0Sm1hME tso6sh 0S 0 M0Shn o0Sh.


If you click the text above, it should “solve out” to a line of text that reads:

The basic idea is to try and generate strings of text that are basically ‘hidden in plain site’ (PUN!) but also generally recognizable as human-written text by retaining much of the punctuation, whitespace, and other elements. This would enable me, for instance, to write text that contained spoilers or had other aspects not intended to be read by The Algorithm while surrounded by text that is perfectly human- and machine-readable. I could say ‘You = poo poo head’ without that being indexed. By keeping it a somewhat simple substitution cypher, this means that it easy for people to translate even without any script and allows it to be relatively undone at a later date.

And then if you click it again (without refreshing the page), it should do essentially nothing. This is my basic first pass on coming up with an idea I have had for Dickens of a Blog since way back. I am unsure when I first posited it but likely around 2006 or 2007.

The idea was simple: set aside some portion of the text in an otherwise open-to-read blog post {e.g., spoilers, info semi-hidden from scrapers, bits that otherwise might be triggers} through a simple enough cipher or baseline encryption that solving it would not become hostile to Doug’s happiness if keys/etc were lost.

The Code Behind It

Version 1 is above. What happens if I have a fairly simple Python code:

from random import sample

def scramble_AlphaNum(oldAlphaNum):
    return ''.join(sample(oldAlphaNum, len(oldAlphaNum)))

alphaNum = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789"
newAlphaNum = scramble_AlphaNum(alphaNum)

text = "The basic idea is to try and generate strings of text that are basically 'hidden in plain site' (PUN!) but also generally recognizable as human-written text by retaining much of the punctuation, whitespace, and other elements. This would enable me, for instance, to write text that contained spoilers or had other aspects not intended to be read by The Algorithm while surrounded by text that is perfectly human- and machine-readable. I could say 'You = poo poo head' without that being indexed. By keeping it a somewhat simple substitution cypher, this means that it easy for people to translate even without any script and allows it to be relatively undone at a later date."
txet = ""
paraName = "demo01"

for t in text:
    try:
        txet = txet + newAlphaNum[alphaNum.index(t)]
    except:
        txet = txet + t
        
output = """ <p id=\"""" + paraName + """\" onclick="gentleScramble('""" + newAlphaNum + """', '""" + paraName + """'); this.onclick=null;">""" + txet + """</p>"""
        
print(output)

Right now, I have to manually edit the file to have the paragraph, div, or span ID and then the contents. It’s fairly trivial to more generalize this. Running that, it spits out a paragraph tag that looks like:

<p id="demo01" onclick="gentleScramble('70u9wOboihzYgVXLamGHINxMAUrsk6CQfcpnv3jS2tR1DB4FJEZdeyWqP8Tl5K', 'demo01'); this.onclick=null;">jLh 903mO moh0 m3 S6 SnE 0so Vhshn0Sh 3SnmsV3 6Y ShFS SL0S 0nh 903mO0MME 'Lmoohs ms QM0ms 3mSh' (C2r!) 9tS 0M36 Vhshn0MME nhO6Vsmd09Mh 03 LtU0s-BnmSShs ShFS 9E nhS0msmsV UtOL 6Y SLh QtsOSt0Sm6s, BLmSh3Q0Oh, 0so 6SLhn hMhUhsS3. jLm3 B6tMo hs09Mh Uh, Y6n ms3S0sOh, S6 BnmSh ShFS SL0S O6sS0msho 3Q6mMhn3 6n L0o 6SLhn 03QhOS3 s6S msShsoho S6 9h nh0o 9E jLh 7MV6nmSLU BLmMh 3tnn6tsoho 9E ShFS SL0S m3 QhnYhOSME LtU0s- 0so U0OLmsh-nh0o09Mh. a O6tMo 30E 'J6t = Q66 Q66 Lh0o' BmSL6tS SL0S 9hmsV msohFho. uE NhhQmsV mS 0 36UhBL0S 3mUQMh 3t93SmStSm6s OEQLhn, SLm3 Uh0s3 SL0S mS h03E Y6n Qh6QMh S6 Sn0s3M0Sh h1hs BmSL6tS 0sE 3OnmQS 0so 0MM6B3 mS S6 9h nhM0Sm1hME tso6sh 0S 0 M0Shn o0Sh.</p>

I add that to my document via Custom HTML. The first string is the randomized a-z/A-Z/0-9 alphanumeric characters of the common American English alphabet (etc). It is randomized per running of the script.

Then at the bottom of the page, I insert another Custom HTML section with this Javascript:

<script>
function gentleScramble(newAlpha,para) {
	const AlphaNum = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
	const newAlphaNum = newAlpha;
	
	let victim = document.getElementById(para).textContent;
	let solution = "";
		
	for (let v = 0; v < victim.length; v++) {
		foundIt = newAlphaNum.indexOf(victim[v]);
		if (foundIt != -1) {
			solution = solution + AlphaNum[foundIt];
		} else {
			solution = solution + victim[v];
		}
	}
		
	document.getElementById(para).textContent=solution;
}
</script>	

That text the paragraph and the substitution cipher and runs it the first click before passing the “this.onclick=null” to stop it from glitching out if a reader spam clicks it.

As it runs through it checks for characters in the defined “alphaNum” and ignores any that are not included. Those that are included it just re-subs them back to their original.

Voila.

Before you might say that this is fairly insecure, that is kind of the point. Is not trying to deeply encode the text, it is more just trying to play at gently hiding the text in a somewhat breakable pattern.

Current Issues

The first issue is that it is pretty hands on to generate the content, which is not 100% a problem for me but if I have several of these elements it will start to wear.

The solution I’m going to do is build a quick tool that allows for different element types {div, p, span} and a bit more of a GUI, probably through just a quick HTML page with text areas and buttons.

The second issue is that it only accepts characters in the a-z/A-Z/0-9 ranges. If I am typing in French and other languages, characters with diacritical marks will be ignored. This means that “ä” will show up as “ä” in the enciphered text. It’s not a deal breaker since the bulk of the text will be gently scrambled, but it can lead to potential weirdness.

The solution to this could be either to scan the contents and generate a shortened “alphaNum” that only includes characters in it while ignoring all the punctuation OR creating a new diaAlphaNum that includes a separate list of diacritically marked text.

I’m not sure which I prefer. I think I prefer to not worry about that so much.

The final issue at a glance is that any HTML elements inside that element {em, a, strong} would likewise be translated which at best would simply glitch them and at worse could in theory create HTML that is broken if it happens to stumble upon a different element than intended.

My solution to this problem is just to not do any of that.

There is a slight non-issue that feed readers and such will likely break in trying to help, but that’s a bit ok for the moment. Not for driving clicks or any such thing, just in that earlier attempts to build CSS/Javascript spoiler type solutions sometimes resulted in said spoilers being clearly visible to feed readers. It does possibly interfere with screen readers and that is a much bigger problem, but I’ll have to test it.

Possibilities for Expansion

My possible end goal for this would include this as a checklist:

  • Perhaps using a Vigenère cipher instead of a simple substitution one [because I prefer those],
  • Making it at least “smart” enough to ignore interior HTML elements, and
  • Generating a bit of styling that makes it more obvious what the reader is supposed to do, possibly including a failsafe type option if the reader has all javascript blocked, etc.

A Day in the Life: #17659

Woke up at 6am to get ready for my morning workout and spent a few minutes, as I do every morning, resting in bed to give my joints time to “calm down.” The arthritis/inflammation-meets-disability tends to be worse after prolonged activity and when I first wake up. I’m sure there’s math to explain the latter. Just know that most of my mornings start with a “Daddy, Chill!” moment between me and my aches.

While resting up for that ten- to twenty-minutes that it takes for my body to realize it is indeed ok to get out of bed, I heard a noise that sounded like someone showering which caught me off guard because I was pretty sure I was the only one awake. Then a few seconds later the wind hit and it turned out that Grimbergen was getting a LOT of wind and rain. It was kind of fun getting up in the pre-sunrise darkness and just watching the rain slam into the side of the house.

Pictured above is my cat, Turkey, pondering why the outside was so blustery. Taken in the moments right before sunrise [the light outside is mostly the streetlights but you can see the sky starting to lighten]. It’s a bit blurry because it was taken in fair darkness and it’s hard to get a photo of a cat while your phone is doing night-photo mode.

At some point I need to find my Nikon and try taking some more proper photos. Not just of weather but also like, you know, heavily macroed shots of rusty nails and stuff.

A Return to “A Day in the Life”

Holy crap, it has been a while since I have used that post title template. In fact, I had to dig through the back-end a bit to find out the previous “Day in the Life” was #14194. That’s over 3000 days ago. Also finding it made me a bit sad. It dealt with a fair amount of negativity. 2016 was a hell of a year. Blogs are truly a double-headed beast.

Just to clarify, in case you are wondering, the Day in the Life posts show the number of days I have been alive, not the number of posts I have made. I used Google to calculate it this time but somewhere in my stacks of files is a Python script I made when I would post these “just stuff I did today” type posts on the old Dickens of a Blog. I should find that. Marvel at how my code used to look. Good marvel? Bad marvel? I don’t know.

#!/usr/bin/python
import datetime
YEAR = 1977
MONTH = 05
DAY = 30

d = "%Y/%m/&d"
today = datetime.date.today()
birth = datetime.date(YEAR, MONTH, DAY)
daysinlife = today - birth
print daysinlife.days

You know, frankly, that’s not too bad. It is clearly Python 2 era. And from the time period where I tended to purposefully over-write code so it was easier for me to chunk and fix later. I’m not even sure what one of those lines is doing in this context. It’s like I copy and pasted it from some other function and just changed the bits I need to change. Let’s show some confidence and fix that up, slightly:

import datetime
print((datetime.date.today() - datetime.date(1977, 5, 30)).days+1)

Voila.

Despite being a person who has been sharing stuff online since the late 90s, and having multiple blogs of which only three have been named “Dickens of a Blog,” it is still a bit odd for me to just share my personal stuff without some major context to sort it through. And possibly that’s because when I get personal I tend to get a bit self-incriminating and self-deprecating. I become that stranger on the bus that starts complaining about his ex-wife and his brother’s dog and stuff his boss said. I mean, maybe not that bad but you get the idea.

At any rate, the “Day in the Life” series was a way for me to have a few dips into those waters on the occasional basis without dealing solely with myself as the main topic. It’s nice to have them back in principle whether or not I use “the brand” all that often. Like most Days in the Life, it is less about a day and more about a bunch of random stuff that has accumulated.

EDIT: Shortly after posting this I realized that my code was still wrong. The way I am wording it would need to include a zero-day. As in, on the date of my birth I would be considering that “Day 1”. I could either set the day to the day before my birth or add 1. I added in a cheeky “+”. That means the title of this is off by a day, but eh. So it goes…

Warning: this one might get a bit over-long as I get back into the balance.

Pommelien Thijs’s Gedoe

Pommelien Thijs’s Gedoe — note, link is in Dutch/Nederlands — came out yesterday so I got to listen to that for a bit. Then more this morning while doing my workout. I really enjoy it.

When we first moved to the Flemish-Brabant/Brussels region, I was trying to absorb some language by listening to local news and such. Thijs kept coming up right as I was breaking into the point of following the slightest bit along. Looking up her music videos, I came across “Ongewoon” [in the context of the song, the line is “Alles voelt zo ongewoon” which is “Everything feels so unusual” but possibly “peculiar” or “strange” or “unfamiliar”…the feeling you get when some preconceived emotions are actually out of whack with expectations] and “Het Midden” [“the middle”] (below):

I enjoyed both of those and other stuff I could find. I’m not a pop-head but still, it was an album I wanted to pick up as I return to getting more physical media, again. I pre-ordered it and ordered her first and got them both in the mail.

The issue at first was how to listen to them. Neither my desktop or laptop have optical disk drives. This means I had to a) get out my external drive that was a still in its box from the move, b) get a voltage converter that we bought early on but have not used yet, c) hook a into b and then plug that into a computer. Then tweak/fix the files I ripped. Being me, I then zipped and cataloged the files and moved them into two different backups.

It’s been a long time since I’ve done a proper review of an album so I am thinking about using that as a guinea pig of such. Maybe. Maybe not.

Barbara’s Assembly

Barbara’s P3 class had their first assembly at her school, yesterday. She spent a fair amount of her own time building up wings using old construction paper and Amazon boxes:

This was all for about half a minute when she was on a stage pretending to be a bird of the Amazon while her class talked about education around the world and how environment impacts education opportunities.

NOTE: I have a photo B wearing her wings but I asked her if she was ok with me sharing and she said no. Since one of the reasons I pulled out of social media because of a personal disagreement with parents oversharing elements of their children’s lives to the wide public, I respect her decision. She was ok with me sharing the wings, though.

Between her planning and construction of a costume largely on her own; her sense of stage direction; and her (at one point) helping another student to remember his lines during the show: she’s a natural stage manager. At eight, she better at handling the chaos of stagecraft than I ever was.

Finally, an American-Style Peanut Butter!

There is actually very little American food that I miss over here with the slight exceptions of Back Home™ has a better selection of types of beans and, via mail order, an overall better selection of TVP (textured vegetable proteins) shapes/sizes. There are plenty of beans here and some variations of soy product [and cheaper soya drink/milk and tofu], but it required some adjustment.

Still, I’ve had a few sad moments where I miss American style peanut butter (or pindakaas [peanut cheese] in Nederlands). Yesterday, swinging by the Carrefour in Vilvoorde, I found this beauty:

I have not been this excited about 2g of added sugars per serving for a minute. I mean, compared to some American foods, this peanut butter is still relatively a healthy food. And, most importantly, it tastes amazing.

I’m not throwing any shade at the availability of plant-based Nutella or the decent selection of other nut butters including some quite decent Belgische pindakaas. It just, good salty-sweet peanut butter hits different.

“Breaking” and Fixing a Garage Door

One aspect of the move that cannot be overstated is how much the large beats are sometimes easy to adapt towards since a lot of support tends to exist to learning the language, replacing electronics, etc but the small beats can practically haunt you as you learn what some minor device or some local custom means. Learning how to say, “Pardon, waar is het toilet?,” can take less time than figuring out how to ask what a small symbol might mean on food packaging when everyone around you thinks of such things as derived from universal common sense. Even somewhat universal symbols can shift slightly enough to imply different things. This is well, good, and expected. Language is a product of the people using it. It just sometimes catches you out.

One way you adjust, which is to say one way that I adjust, is just occasionally pushing a button or pulling a string to see what happens. Buy the product. Tap the card.

This morning, post-workout, I realized our garage had a pull cord and so I went, “Hmm, ik kan aan dit koord trekken.” And then a loud pop answered my call as the cord turned out to be a release to detach the door from the mechanism.

Kaz and I fixed it shortly after but it was a good life lesson. Push the buttons, pull the cords, and bring a toolbox to fix the fallout when you do.

With the above photo, don’t sweat about the power cord with duct tape. It’s not actually plugged in. We’ll replace it if we ever need to use it.

Powered by WordPress & Theme by Anders Norén