Commit 73d86f4c authored by nervuri's avatar nervuri
Browse files

generate atom feed; refactor

parent b6a7c7f7
Pipeline #327917999 passed with stage
in 19 seconds
......@@ -19,8 +19,8 @@
,####.
.######.
```
=> zero-width.gmi Zero-width character test
=> stega.gmi Tracking via pasted text
=> zero-width.gmi Zero-width character test
=> gemlog/ gemlog
......
......@@ -92,8 +92,8 @@ An almost perfect non-technical solution is to retype the text. You can also tr
=> https://www.unicode.org/faq/security.html Unicode Security Issues FAQ
=> https://www.unicode.org/reports/tr36/ Unicode Security Considerations - Technical Report
_________________________
Created: 2021-02-20
Last modified: 2021-05-10
_____________________
Published: 2021-02-20
Updated: 2021-05-10
=> https://gitlab.com/nervuri/nervuri.net/-/blob/master/gemini/stega.gmi Source (contributions welcome)
=> https://creativecommons.org/licenses/by-sa/4.0/ License: CC-BY-SA
......@@ -78,8 +78,8 @@ This test page is also available on Gopher and the Web:
=> gemini://rawtext.club/~nervuri/contact.gmi contact info
_________________________
Created: 2021-02-20
Last modified: 2021-03-20
_____________________
Published: 2021-02-20
Updated: 2021-03-20
=> https://gitlab.com/nervuri/nervuri.net/-/blob/master/gemini/zero-width.gmi Source (contributions welcome)
=> https://creativecommons.org/licenses/by-sa/4.0/ License: CC-BY-SA
......@@ -6,6 +6,18 @@ from subprocess import call
from pathlib import Path
import sys
feed = {
'updated': '',
'author': 'nervuri',
'rights': 'CC-BY-SA unless otherwise specified - https://creativecommons.org/licenses/by-sa/4.0/',
'entries': [],
}
license_links = {
'CC-BY-SA': 'https://creativecommons.org/licenses/by-sa/4.0/',
'MPL-2.0': 'https://tldrlegal.com/license/mozilla-public-license-2.0-(mpl-2)',
}
def makepage(md_path):
# prune the path:
......@@ -18,7 +30,7 @@ def makepage(md_path):
'article': 'false',
}
with open(md_path) as md_file:
with open(md_path, 'r') as md_file:
# read the first part of the file as metadata
for line in md_file:
if line.startswith('~'):
......@@ -35,29 +47,62 @@ def makepage(md_path):
TITLE = metadata['title'],
)
# generate article html
if metadata['article'] == 'true':
main = '<article>\n' + main + '\n</article>\n\n'
# add footer
main += '<hr>\n\n'
main += '<footer class="bottom">\n'
if 'created' in metadata:
main += 'Created: <time datetime="{0}">{0}</time><br>\n'.format(metadata['created'])
if 'last modified' in metadata:
main += 'Last modified: <time datetime="{0}">{0}</time><br>\n'.format(metadata['last modified'])
if 'published' in metadata:
main += 'Published: <time datetime="{0}">{0}</time><br>\n'.format(metadata['published'])
if 'updated' in metadata:
main += 'Updated: <time datetime="{0}">{0}</time><br>\n'.format(metadata['updated'])
if 'source' in metadata:
main += '<a href="{0}">Source</a> (contributions welcome)<br>\n'.format(metadata['source'])
if 'license' in metadata:
if metadata['license'] == 'CC-BY-SA':
main += 'License: <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a>\n'
elif metadata['license'] == 'MPL-2.0':
main += 'License: <a href="https://tldrlegal.com/license/mozilla-public-license-2.0-(mpl-2)">MPL-2.0</a>\n'
if metadata['license'] in license_links:
main += 'License: <a href="' + license_links[metadata['license']] + '">' + metadata['license'] + '</a>\n'
else:
main += 'License: ' + metadata['license'] + '\n'
main += '</footer>'
template_file = open('template.tpl')
template = Template(template_file.read())
template_file.close()
# add to feed
if pruned_path == 'index': # if index page
feed['title'] = metadata['title']
feed['subtitle'] = metadata['description']
feed['link_alt'] = { 'text/html': metadata['web'] }
# Feedreaders behave inconsistently when multiple alternate
# links are present, even though the Atom spec allows it.
#if 'gemini' in metadata:
# feed['link_alt']['text/gemini'] = metadata['gemini']
#if 'gopher' in metadata:
# feed['link_alt']['text/plain'] = metadata['gopher']
feed['link_self'] = metadata['web'] + 'feed.atom'
feed['icon'] = metadata['web'] + 'favicon.ico'
feed['id'] = metadata['web']
elif metadata['article'] == 'true':
entry = {}
entry['title'] = metadata['title']
entry['link_alt'] = { 'text/html': metadata['web'] }
# Feedreaders behave inconsistently when multiple alternate
# links are present, even though the Atom spec allows it.
#if 'gemini' in metadata:
# entry['link_alt']['text/gemini'] = metadata['gemini']
#if 'gopher' in metadata:
# entry['link_alt']['text/plain'] = metadata['gopher']
entry['id'] = metadata['web']
entry['published'] = metadata['published']
entry['updated'] = metadata['updated']
if metadata['license'] in license_links:
entry['rights'] = metadata['license'] + ' - ' + license_links[metadata['license']]
else:
entry['rights'] = metadata['license']
entry['summary'] = metadata['description']
entry['content'] = main
feed['entries'].append(entry)
with open('templates/main.tpl', 'r') as f:
main_template = Template(f.read())
extra_tags = ''
if 'description' in metadata:
......@@ -72,7 +117,7 @@ def makepage(md_path):
path += '../'
top = ''
if metadata['title'] != 'nervuri': # if not index page
if pruned_path != 'index': # if not index page
metadata['title'] += ' | nervuri'
# add top section
other_protocols = ''
......@@ -82,31 +127,33 @@ def makepage(md_path):
if 'gopher' in metadata:
other_protocols += '<a href="' + metadata['gopher'] + '">gopher</a>' +\
'(<a href="https://gopher.floodgap.com/overbite/relevance.html" title="What is Gopher?">?</a>) |\n '
template_top_file = open('template-top.tpl')
template_top = Template(template_top_file.read())
template_top_file.close()
top = template_top.substitute(
with open('templates/top.tpl', 'r') as f:
top_template = Template(f.read())
top = top_template.substitute(
OTHER_PROTOCOLS = other_protocols,
PATH = path,
)
fileout = open('public/' + pruned_path + '.html', 'w')
fileout.write(template.substitute(
page_html = main_template.substitute(
PATH = path,
TITLE = metadata['title'],
EXTRA_TAGS = extra_tags,
MAIN = main,
TOP = top,
))
fileout.close()
)
with open('public/' + pruned_path + '.html', 'w') as f:
f.write(page_html)
############################################################
### make html files ###
page_to_open = ''
# If path is provided to a .md file is provided, make only that page.
# Else, make all pages.
# Else, make all pages + Atom feed.
if len(sys.argv) > 1:
md_path = sys.argv[1]
if md_path[:9] != 'markdown/':
......@@ -125,9 +172,64 @@ else:
page_to_open = str(md_path)
makepage(md_path)
call(['netsigil', '--sign', 'public/'])
### make feed ###
# sort entries by 'updated'
feed['entries'] = sorted(feed['entries'], key=lambda k: k['updated'], reverse=True)
# feed['updated'] -> most recent updated entry
feed['updated'] = feed['entries'][0]['updated']
with open('templates/feed.tpl', 'r') as f:
feed_template = Template(f.read())
with open('templates/feed-entry.tpl', 'r') as f:
feed_entry_template = Template(f.read())
entries = ''
for entry in feed['entries']:
link_alt = ''
for mimetype, link in entry['link_alt'].items():
link_alt += f' <link type="{mimetype}" href="{link}" />\n'
entries += feed_entry_template.substitute(
TITLE = entry['title'],
ID = entry['id'],
LINK_ALT = link_alt,
PUBLISHED = entry['published'],
UPDATED = entry['updated'],
SUMMARY = entry['summary'],
CONTENT = entry['content'],
RIGHTS = entry['rights'],
)
link_alt = ''
for mimetype, link in feed['link_alt'].items():
link_alt += f' <link rel="alternate" type="{mimetype}" href="{link}" />\n'
feed_xml = feed_template.substitute(
TITLE = feed['title'],
SUBTITLE = feed['subtitle'],
ID = feed['id'],
LINK_ALT = link_alt,
LINK_SELF = feed['link_self'],
ICON = feed['icon'],
UPDATED = feed['updated'],
AUTHOR = feed['author'],
RIGHTS = feed['rights'],
ENTRIES = entries,
)
with open('public/feed.atom', 'w') as f:
f.write(feed_xml)
### sign website ###
call(['netsigil', '--sign', 'public/'])
############################################################
### open last modified page in browser ###
# Open in browser; first prune the path:
# First prune the path:
# markdown/path/file.md -> path/file
pruned_path = page_to_open[9:][:-3]
call(['xdg-open', 'public/' + pruned_path + '.html'])
......@@ -3,7 +3,7 @@ ___ nervuri ___
"To create a little flower is the labour of ages"
- William Blake
0Zero-width character test zero-width.txt
0Tracking via pasted text stega.txt
0Zero-width character test zero-width.txt
0contact contact.txt
......@@ -181,9 +181,9 @@ https://www.unicode.org/faq/security.html
Unicode Security Considerations - Technical Report:
https://www.unicode.org/reports/tr36/
_________________________
Created: 2021-02-20
Last modified: 2021-05-10
_____________________________________________________________________
Published: 2021-02-20
Updated: 2021-05-10
Source (contributions welcome):
https://gitlab.com/nervuri/nervuri.net/-/blob/master/gopher/stega.txt
......
......@@ -86,9 +86,9 @@ https://nervuri.net/zero-width
gopher://rawtext.club:70/0/~nervuri/contact.txt
_________________________
Created: 2021-02-20
Last modified: 2021-03-20
__________________________________________________________________________
Published: 2021-02-20
Updated: 2021-03-20
Source (contributions welcome):
https://gitlab.com/nervuri/nervuri.net/-/blob/master/gopher/zero-width.txt
......
......@@ -12,9 +12,9 @@ gopher: gopher://rawtext.club/1/~nervuri/
<figcaption>Din lumină foșnet soarbe</figcaption>
</figure>
<p>
<a href="zero-width">Zero-width character test</a><br>
<a href="stega">Tracking via pasted text</a><br>
<a href="zero-width">Zero-width character test</a><br>
<a href="fragment-search/">URI fragment search</a><br>
<a href="contact">contact</a> | <a href="https://nitter.nixnet.services/nervuri/rss" title="subscribe"><img src="img/feed-13.png" alt="subscribe" width="13" height="13" class="feed"></a>
<a href="contact">contact</a> | <a href="feed.atom" title="subscribe"><img src="img/feed-13.png" alt="subscribe" width="13" height="13" class="feed"></a>
</p>
</center></div>
......@@ -2,8 +2,8 @@ title: Tracking via pasted text
article: true
description: Plain text steganography and how it can be used against you
keywords: privacy, unicode, steganography
created: 2021-02-20
last modified: 2021-05-10
published: 2021-02-20
updated: 2021-05-10
web: https://nervuri.net/stega
gemini: gemini://rawtext.club/~nervuri/stega.gmi
gopher: gopher://rawtext.club/0/~nervuri/stega.txt
......
title: Zero-width character test
article: true
description: Test if you are protected against tracking via zero-width characters
description: Test if your software displays zero-width characters
keywords: privacy, unicode, steganography
created: 2021-02-20
last modified: 2021-03-12
published: 2021-02-20
updated: 2021-03-12
web: https://nervuri.net/zero-width
gemini: gemini://rawtext.club/~nervuri/zero-width.gmi
gopher: gopher://rawtext.club/0/~nervuri/zero-width.txt
......
......@@ -10,7 +10,7 @@
<meta name="keywords" content="contact, e-mail">
<link rel="canonical" href="https://nervuri.net/contact">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="https://nitter.nixnet.services/nervuri/rss">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="feed.atom">
<link rel="pgpkey authn" href="keys/nervuri-gpg.pub">
<link rel="webmention" href="https://webmention.io/nervuri.net/webmention">
......@@ -23,7 +23,7 @@
<span style="float: right">
<a href="gemini://rawtext.club/~nervuri/contact.gmi">gemini</a>(<a href="https://gemini.circumlunar.space/" title="What is Gemini?">?</a>) |
<a href="gopher://rawtext.club/0/~nervuri/contact.txt">gopher</a>(<a href="https://gopher.floodgap.com/overbite/relevance.html" title="What is Gopher?">?</a>) |
<a href="https://nitter.nixnet.services/nervuri/rss"><img src="img/feed-13.png" alt="subscribe" title="subscribe" width="13" height="13" class="feed"></a>
<a href="feed.atom"><img src="img/feed-13.png" alt="subscribe" title="subscribe" width="13" height="13" class="feed"></a>
</span>
<hr>
</nav>
......
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>nervuri</title>
<subtitle>“To create a little flower is the labour of ages” (William Blake)</subtitle>
<id>https://nervuri.net/</id>
<link rel="alternate" type="text/html" href="https://nervuri.net/" />
<link rel="self" href="https://nervuri.net/feed.atom" />
<icon>https://nervuri.net/favicon.ico</icon>
<updated>2021-05-10T00:00:00Z</updated>
<author>
<name>nervuri</name>
</author>
<rights>CC-BY-SA unless otherwise specified - https://creativecommons.org/licenses/by-sa/4.0/</rights>
<entry>
<title>Tracking via pasted text</title>
<id>https://nervuri.net/stega</id>
<link type="text/html" href="https://nervuri.net/stega" />
<published>2021-02-20T00:00:00Z</published>
<updated>2021-05-10T00:00:00Z</updated>
<summary>Plain text steganography and how it can be used against you</summary>
<content type="html"><![CDATA[<article>
<p><center>
<div class="center">
<img src="img/backstab.gif" alt="backstab" title="betrayed by technology" width="309" height="300">
<!-- image source: https://www.cinejosh.com/news/3/33445/backstabbing-trending-in-current-politics.html -->
<h1>Tracking via pasted text</h1>
<p><i>Plain text steganography and how it can be used against you</i></p>
</div>
</center></p>
<p><a href="https://en.wikipedia.org/wiki/Zero-width_space">Zero-width characters</a> can be used to embed hidden information inside of plain text. This is of primary concern to journalists and their sources, but it can affect anyone browsing the Internet. For example, a page can be dynamically generated server-side to include, between every few words:</p>
<ul>
<li>your username / <a href="https://en.wikipedia.org/wiki/Client_certificate">certificate ID</a> (if logged in)</li>
<li>your IP address</li>
<li>the current timestamp</li>
</ul>
<p>By copying text from the page and pasting it somewhere public, you would be revealing this information to anyone who knew how to look for it. Details and demo in this article:</p>
<p><a href="https://medium.com/@umpox/be-careful-what-you-copy-invisibly-inserting-usernames-into-text-with-zero-width-characters-18b4e6f17b66">Be careful what you copy: Invisibly inserting usernames into text with Zero-Width Characters (Tim Ross, 2018)</a></p>
<p>To check if your browser displays zero-width characters, open:</p>
<ul>
<li><strong><a href="zero-width">Zero-width character test</a></strong></li>
</ul>
<p>Other plain text watermarking techniques / canary traps are explained on Zach Aysan's blog:</p>
<ul>
<li><a href="https://www.zachaysan.com/writing/2017-12-30-zero-width-characters">Zero-Width Characters: Invisibly fingerprinting text (2017)</a></li>
<li><a href="https://www.zachaysan.com/writing/2018-01-01-fingerprinting-update">Text Fingerprinting Update: Stories and ideas from readers (2018)</a></li>
</ul>
<p>To fingerprint text, server software would only need to encode a hidden number inside it, repeated between every few words, matching a log entry that contains information about the visitor (username, IP address, cookie, browser details, referrer link, timestamp). For easily finding pasted excerpts online, the software could similarly hide a unique page-specific identifier within the text, that can later be put into search engines.</p>
<p>To achieve this, aside from zero-width characters, the software could use some of the other techniques described by Zach Aysan: <em>"differences in dashes (en, em, and hyphens), quotes (straight vs curly), word spelling (color vs colour), and the number of spaces after sentence endings"</em>, different <a href="https://www.jkorpela.fi/chars/spaces.html">types of spaces</a>, <a href="https://en.wikipedia.org/wiki/Homoglyph">homoglyphs</a> (a vs а), diacritic forms (ț vs ţ), ligatures (fi vs fi, Ⅳ vs IV, ½ vs 1/2), as well as inserting hard to detect typos into the text.</p>
<h2 id="solutions"><a class="toclink" href="#solutions">Solutions</a></h2>
<p>A partial solution is to convert the text to <a href="https://en.wikipedia.org/wiki/ASCII">ASCII</a>, if language allows. There are also tools such as:</p>
<ul>
<li><a href="https://www.greenwoodsoftware.com/less/">Less (CLI)</a> - displays zero-width characters when used with the "-U" option.</li>
<li><a href="https://github.com/DavidJacobson/SafeText">SafeText (CLI)</a> - also detects some homoglyphs. It started out well, but development has stopped; in its current state, there are many problematic characters that it does not detect - see <a href="https://github.com/DavidJacobson/SafeText/issues">issues</a>.</li>
<li>Several browser extensions that detect <strong>a few</strong> zero-width characters.</li>
</ul>
<p>However, they don't protect against the more sophisticated versions of this hack. A more complete tool would have to include not just a list of forbidden/allowed characters, but also a a spellchecker and a way to detect trailing whitespace - an x-ray mode that might be triggered when dubious text is detected in the clipboard. And not just text, image-based steganography can be used in a similar way. A technical solution might never be perfect, but it could cover the vast majority of cases.</p>
<p>An almost perfect non-technical solution is to retype the text. You can also try downloading the page twice from different accounts / IP addresses and <a href="https://en.wikipedia.org/wiki/Diff">diff</a> the two versions, or check if the hashes match. Another solution is to take a screenshot of the text and run it through <a href="https://en.wikipedia.org/wiki/Optical_character_recognition">OCR</a> software.</p>
<h2 id="tools-for-text-steganography"><a class="toclink" href="#tools-for-text-steganography">Tools for text steganography</a></h2>
<ul>
<li><a href="https://github.com/KuroLabs/stegcloak">StegCloak</a></li>
<li><a href="https://www.spammimic.com/">Spam Mimic</a> (see Encode -&gt; Alternate encodings)</li>
<li><a href="https://github.com/vedhavyas/zwfp">zwfp</a></li>
<li><a href="http://www.darkside.com.au/snow/">SNOW</a></li>
<li><a href="https://web.archive.org/web/20180217185500/http://mok-kong-shen.de:80/">WORDLISTTEXTSTEGANOGRAPHY &amp; EMAILSTEGANO</a></li>
<li><a href="https://git.planetrenox.com/inzerosight/browser-extension">inØsight — Zero Width Obfuscation</a> (extension for Firefox and Chromium)</li>
<li><a href="https://zws.im/">Zero Width Shortener</a> - Shorten URLs using invisible spaces</li>
</ul>
<p><a href="https://www.fileformat.info/info/unicode/char/search.htm">Unicode character search</a></p>
<h2 id="further-reading"><a class="toclink" href="#further-reading">Further reading</a></h2>
<h3 id="text-steganography"><a class="toclink" href="#text-steganography">Text steganography</a></h3>
<ul>
<li><a href="https://www.researchgate.net/publication/321844767_Text_based_steganography">Text based steganography (Robert Lockwood and Kevin Curran, 2017)</a></li>
<li><a href="https://www.ijcsi.org/papers/IJCSI-9-4-3-401-405.pdf">Text Steganography with Multi level Shielding (Sharon Rose Govada et al., 2012)</a></li>
<li><a href="https://crypto.stackexchange.com/questions/6058/any-efficient-text-based-steganographic-schemes">Any efficient text-based steganographic schemes? (crypto.stackexchange.com)</a></li>
<li><a href="https://security.stackexchange.com/questions/20414/steganography-to-hide-text-within-text">Steganography to hide text within text (security.stackexchange.com)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Chaffing_and_winnowing">Chaffing and winnowing (Wikipedia)</a></li>
</ul>
<h3 id="control-characters"><a class="toclink" href="#control-characters">Control characters</a></h3>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Zero-width_space">Zero-width space (Wikipedia)</a></li>
<li><a href="https://www.ptiglobal.com/2018/04/26/the-beauty-of-unicode-zero-width-characters/">Article explaining the role of a few zero-width characters</a></li>
<li><a href="https://www.jkorpela.fi/chars/spaces.html">Partial list of Unicode spaces</a></li>
<li><a href="https://en.wikipedia.org/wiki/Unicode_control_characters">Unicode control characters (Wikipedia)</a></li>
<li><a href="https://en.wikipedia.org/wiki/Tags_(Unicode_block)">Tags (Unicode block) (Wikipedia)</a></li>
<li><a href="https://www.unicode.org/Public/UCD/latest/">Unicode Character Database</a></li>
</ul>
<h3 id="homoglyphs"><a class="toclink" href="#homoglyphs">Homoglyphs</a></h3>
<ul>
<li><a href="https://en.wikipedia.org/wiki/Homoglyph">Homoglyph (Wikipedia)</a></li>
<li><a href="https://www.unicode.org/reports/tr39/#Confusable_Detection">Confusable detection</a></li>
<li><a href="https://unicode.org/Public/security/latest/confusables.txt">confusables.txt</a></li>
</ul>
<h3 id="nfkc-normalisation"><a class="toclink" href="#nfkc-normalisation">NFKC normalisation</a></h3>
<ul>
<li><a href="https://github.com/DavidJacobson/SafeText/issues/1">"Apply NFKC normalisation" - SafeText issue</a></li>
<li><a href="https://www.unicode.org/faq/normalization.html">Unicode Normalization FAQ</a></li>
<li><a href="https://unicode.org/reports/tr15/">Unicode Normalization Forms</a></li>
</ul>
<h3 id="unicode-security-considerations"><a class="toclink" href="#unicode-security-considerations">Unicode security considerations</a></h3>
<ul>
<li><a href="https://www.unicode.org/faq/security.html">Unicode Security Issues FAQ</a></li>
<li><a href="https://www.unicode.org/reports/tr36/">Unicode Security Considerations - Technical Report</a></li>
</ul>
</article>
<hr>
<footer class="bottom">
Published: <time datetime="2021-02-20">2021-02-20</time><br>
Updated: <time datetime="2021-05-10">2021-05-10</time><br>
<a href="https://gitlab.com/nervuri/nervuri.net/-/blob/master/markdown/stega.md">Source</a> (contributions welcome)<br>
License: <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a>
</footer>]]></content>
<rights>CC-BY-SA - https://creativecommons.org/licenses/by-sa/4.0/</rights>
</entry>
<entry>
<title>Zero-width character test</title>
<id>https://nervuri.net/zero-width</id>
<link type="text/html" href="https://nervuri.net/zero-width" />
<published>2021-02-20T00:00:00Z</published>
<updated>2021-03-12T00:00:00Z</updated>
<summary>Test if your software displays zero-width characters</summary>
<content type="html"><![CDATA[<article>
<p><center>
<div class="center">
<h1>Zero-width character test</h1>
</div>
</center></p>
<p>Below are 34 zero-width Unicode characters, placed between underscores. Does your browser display them? Your text editor? Your terminal? To understand why not displaying them might be a problem, read:</p>
<p><a href="stega">Tracking via pasted text</a></p>
<p>As a point of reference, here are a few positive-width Unicode characters:</p>
<pre><code>0020: _ _ | 00E9: _é_ | 03A9: _Ω_ | 5B57: _字_ | 1F407: _🐇_
</code></pre>
<h2 id="zero-width-characters"><a class="toclink" href="#zero-width-characters">Zero-width characters</a></h2>
<pre><code> 061C: _؜_
180E: _᠎_
200B: _​_
200C: _‌_
200D: _‍_
200E: __
200F: __
202A: __
202B: __
202C: __
202D: __
202E: __
2060: _⁠_
2061: _⁡_
2062: _⁢_
2063: _⁣_
2064: _⁤_
2066: __
2067: __
2068: __
2069: __
206A: __
206B: __
206C: __
206D: __
206E: __
206F: __
FEFF: __
FFF9: __
FFFA: __
FFFB: __
E0001: _󠀁_
E0020: _󠀠_
... (E0020–E007F formerly used for tagging texts by language)
E007F: _󠁿_
</code></pre>
<p>This is probably not a complete list. <a href="contact">Contact me</a> if you know of any others.</p>
<p>As of February 2020, Unicode contains 143,859 characters.</p>
<p><a href="https://www.unicode.org/Public/UCD/latest/">Unicode Character Database</a></p>
<h2 id="programs-which-pass-the-test"><a class="toclink" href="#programs-which-pass-the-test">Programs which pass the test</a></h2>
<ul>
<li><a href="https://www.greenwoodsoftware.com/less/">Less</a> - when used with the "-U" option</li>
</ul>
<p><a href="contact">Contact me</a> if you know of any others.</p>
<p>This test is also available <a href="https://gitlab.com/nervuri/nervuri.net/-/raw/master/gopher/zero-width.txt">as a plain .txt file</a>.</p>
</article>
<hr>
<footer class="bottom">
Published: <time datetime="2021-02-20">2021-02-20</time><br>
Updated: <time datetime="2021-03-12">2021-03-12</time><br>
<a href="https://gitlab.com/nervuri/nervuri.net/-/blob/master/markdown/zero-width.md">Source</a> (contributions welcome)<br>
License: <a href="https://creativecommons.org/licenses/by-sa/4.0/">CC-BY-SA</a>
</footer>]]></content>
<rights>CC-BY-SA - https://creativecommons.org/licenses/by-sa/4.0/</rights>
</entry>
</feed>
......@@ -10,7 +10,7 @@
<meta name="keywords" content="privacy, freedom">
<link rel="canonical" href="https://nervuri.net/">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="https://nitter.nixnet.services/nervuri/rss">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="feed.atom">
<link rel="pgpkey authn" href="keys/nervuri-gpg.pub">
<link rel="webmention" href="https://webmention.io/nervuri.net/webmention">
......@@ -25,10 +25,10 @@
<figcaption>Din lumină foșnet soarbe</figcaption>
</figure>
<p>
<a href="zero-width">Zero-width character test</a><br>
<a href="stega">Tracking via pasted text</a><br>
<a href="zero-width">Zero-width character test</a><br>
<a href="fragment-search/">URI fragment search</a><br>
<a href="contact">contact</a> | <a href="https://nitter.nixnet.services/nervuri/rss" title="subscribe"><img src="img/feed-13.png" alt="subscribe" width="13" height="13" class="feed"></a>
<a href="contact">contact</a> | <a href="feed.atom" title="subscribe"><img src="img/feed-13.png" alt="subscribe" width="13" height="13" class="feed"></a>
</p>
</center></div>
</main>
......
......@@ -10,7 +10,7 @@
<meta name="keywords" content="PGP, GPG, signify, signature, NetSigil">
<link rel="canonical" href="https://nervuri.net/keys/">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="https://nitter.nixnet.services/nervuri/rss">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="../feed.atom">
<link rel="pgpkey authn" href="../keys/nervuri-gpg.pub">
<link rel="webmention" href="https://webmention.io/nervuri.net/webmention">
......@@ -23,7 +23,7 @@
<span style="float: right">
<a href="gemini://rawtext.club/~nervuri/keys/">gemini</a>(<a href="https://gemini.circumlunar.space/" title="What is Gemini?">?</a>) |
<a href="gopher://rawtext.club/0/~nervuri/keys/keys.txt">gopher</a>(<a href="https://gopher.floodgap.com/overbite/relevance.html" title="What is Gopher?">?</a>) |
<a href="https://nitter.nixnet.services/nervuri/rss"><img src="../img/feed-13.png" alt="subscribe" title="subscribe" width="13" height="13" class="feed"></a>
<a href="../feed.atom"><img src="../img/feed-13.png" alt="subscribe" title="subscribe" width="13" height="13" class="feed"></a>
</span>
<hr>
</nav>
......
......@@ -10,7 +10,7 @@
<meta name="keywords" content="privacy, unicode, steganography">
<link rel="canonical" href="https://nervuri.net/stega">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="https://nitter.nixnet.services/nervuri/rss">
<link rel="alternate" type="application/atom+xml" title="nervuri feed" href="feed.atom">
<link rel="pgpkey authn" href="keys/nervuri-gpg.pub">
<link rel="webmention" href="https://webmention.io/nervuri.net/webmention">
......@@ -23,7 +23,7 @@
<span style="float: right">
<a href="gemini://rawtext.club/~nervuri/stega.gmi">gemini</a>(<a href="https://gemini.circumlunar.space/" title="What is Gemini?">?</a>) |
<a href="gopher://rawtext.club/0/~nervuri/stega.txt">gopher</a>(<a href="https://gopher.floodgap.com/overbite/relevance.html" title="What is Gopher?">?</a>) |
<a href="https://nitter.nixnet.services/nervuri/rss"><img src="img/feed-13.png" alt="subscribe" title="subscribe" width="13" height="13" class="feed"></a>
<a href="feed.atom"><img src="img/feed-13.png" alt="subscribe" title="subscribe" width="13" height="13" class="feed"></a>
</span>
<hr>