Wolfram Function Repository
Instant-use add-on functions for the Wolfram Language
Function Repository Resource:
Hide an invisible textual watermark within a string
ResourceFunction["TextWatermark"][text,watermark] embeds watermark in text without affecting the display of text. | |
ResourceFunction["TextWatermark"][text] retrieves the watermark embedded in text. |
Method | "InvisibleSpace" | how the watermark is encoded |
"Sparsity" | 1 | how frequently additional characters are inserted |
"InvisibleSpace" | may insert an invisible space character (Unicode 8203) after every space (Unicode 13) in the original text |
"InvisibleDense" | may insert an invisible space character (Unicode 8203) after any character in the original text |
"Space" | may insert a space character (ASCII 13) after punctuation marks |
"SpaceDense" | may insert a space character (ASCII 13) after punctuation marks and other non-letter characters |
Insert the a watermark into the text of Alice in Wonderland:
In[1]:= |
Out[1]= |
Retrieve the watermark:
In[2]:= |
Out[2]= |
The watermark is added repeatedly, so any sufficiently long sequence of the text will contain the watermark:
In[3]:= |
In[4]:= |
Out[4]= |
By default, information is encoded using the invisible space character (UNICODE 8203, Hex 200b). If the text is displayed in software which does not render invisible space then the encoding will be visible to the reader:
In[5]:= |
Out[6]= |
Use Method→"Space" to insert standard space characters (ASCII 32); however, the result will not appear identical to the original (note the lack of space after "to do.":
In[7]:= |
Out[7]= |
In[8]:= |
Out[8]= |
TextWatermark inserts information greedily depending on the Method used. In this example, 26 invisible spaces are inserted in the first 300 characters:
In[9]:= |
Out[9]= |
Use fewer opportunities to make the watermark less detectable. Higher "Sparsity" will require more carrier text to embed the watermark into:
In[10]:= |
Out[10]= |
The typical application is to create unique versions of secret text for each reader so that, if the text is leaked, it is possible to trace which reader was responsible:
In[11]:= |
Out[11]= |
If there is insufficient carrier text to encode the watermark into, TextWatermark will attempt to switch method from "InvisibleSpace" to "InvisibleSpaceDense" or "Space" to "SpaceDense", and if it still cannot succeed, will return $Failed
In[12]:= |
Out[12]= |
When decoding watermarks, it is not known which embedding method has been used, so each is performed in turn. There is a small risk that a spurious message is generated. This process is also slower than manually specifying the Method when decoding:
In[13]:= |
In[14]:= |
Out[14]= |
This work is licensed under a Creative Commons Attribution 4.0 International License