7

I would like to print a number of 256-bit long hashes in hexadecimal (so 64 characters, I'm skipping the usual "0x" without white spaces or punctuation) in line and using a monospaced font.

So, I first went for \texttt, which does not hyphenate my strings. I saw some questions with interesting answers, such as How to get long \texttt sections to break and Automatic linebreak on specific character but those both define linebreak for a specific character and I would find ugly to use their trick for each of the 16 characters of hexadecimal without some sort of natural loop.

Is there a way to define a command such that the text inside will be typed as texttt but break on any character or, even better, a standard way to typeset long hexadecimal strings that takes this issue into account?

MWE:

\documentclass{article}

\newcommand{\hash}[1]{\texttt{#1}}%In a perfect world, this would be changed to allow linebreaks anywhere in #1

\begin{document}
SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
\end{document}
Anab
  • 355

4 Answers4

11

There is already a package for this:

\documentclass{article}
\usepackage{seqsplit}

\newcommand{\hash}[1]{{\ttfamily\seqsplit{#1}}}

\begin{document}

SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}

\end{document}

enter image description here

Without packages:

\documentclass{article}

\ExplSyntaxOn \NewDocumentCommand{\hash}{O{\ttfamily}m} { \group_begin: #1 % font choice, default \ttfamily \tl_map_function:nN { #2 } __anab_hash_char:n \group_end: } \cs_new:Nn __anab_hash_char:n { #1 \skip_horizontal:n { 0pt plus 0.2pt } } \ExplSyntaxOff

\begin{document}

SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}

\noindent\parbox[t]{0.4\textwidth}{% SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15} }\quad \parbox[t]{0.4\textwidth}{% SHA-256 is a hash function with a 256-bit long output: \hash[\sffamily]{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15} }

\end{document}

enter image description here

egreg
  • 1,121,712
7

You can add a penalty after each character

enter image description here

\documentclass{article}

\newcommand{\hash}[1]{\texttt{\zz#1\zz}}%In a perfect world, this would be changed to allow linebreaks anywhere in #1

\def\zz#1{%
 \ifx\zz#1\else
   #1\linebreak[1]\expandafter\zz
 \fi}

\begin{document}
SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}
\end{document}
David Carlisle
  • 757,742
  • Thanks, this does exactly what I wanted! I am just a bit curious as to how that works: is it a recursion that does nothing if #1 is empty (stopping condition) or else suggests a line break at the current position? – Anab Aug 09 '16 at 18:39
  • 1
    @Anab it recurses through each character adding a potential breakpoint stopping when it sees the \zz that is placed at the end. – David Carlisle Aug 09 '16 at 18:44
  • Thanks, that's what I thought was going on but my TeX was not nearly good enough for me to be sure of it without asking. :) – Anab Aug 09 '16 at 18:49
  • @DavidCarlisle Nice. But this \hash{\char"02C6} (or \hash{\char"02C6{}}) breaks it. Is there a way to modify your code to cope with hexidecimal/octal/substitution-denoted characters? – Jonathan Komar Mar 22 '18 at 12:18
  • @JonathanKomar why input them that way? input them as a single character ˆ or as ^^^^02c6 – David Carlisle Mar 22 '18 at 12:22
  • Aren't hexidecimal-denoted characters acceptable in documents? I'd prefer to write redefinitions that support the capability of the original definitions. I suppose that is the main reason. ^^^^02c6 is interesting and confusing syntax. I have never seen that before. – Jonathan Komar Mar 22 '18 at 12:26
  • 1
    @JonathanKomar ^^^^02c6 is the hex representation of the character, it is a single character token that can be used anywhere a character can be used eg \^^^^02c6 would be a command token with that name. \char"02C6 is completely different it is 6 tokens invoking a non-expandable sequence of instructions which if used in a typesetting context will access the the glyph from the font with number hex 02C6. – David Carlisle Mar 22 '18 at 13:00
  • @DavidCarlisle Cool, nice to learn something new. In the meantime, I provided an alternative answer that addresses my concern. – Jonathan Komar Mar 22 '18 at 13:35
  • This method doesn't keep whitespace. It is used for display sequence without whitespace. – Tokubara Apr 08 '23 at 09:24
3

Solution Making TeX Treat Characters like Words

This works, but has the limitation that denoted characters do not work. e.g. using hexidecimal (\char"02C6) or octal notation.

\documentclass{article}

\def\hash#1{\xscan#1\relax}% calls xscan which looks ahead one token, #1 \def\xscan{\afterassignment\xxscan\let\token= }% assign single token to \token and call \xxscan \def\xxscan{% \ttfamily% set font style \ifx\token\relax\ttfamily\else%test for end-of-line or end of group and switch to ttfamily \ifcat\token\space% \token% token is catcode 10 \spaceskip=.5em% remove glue from space for fixed-width space \xspaceskip=.5em% remove glue from space for fixed-width space \else% \token\hskip 0pt plus 1sp minus 1sp % add glue to any non-catcode 10 (space) \fi \spaceskip=0pt% reset space skip \expandafter\xscan% feed next token to \xscan, which is effectively a recursive call \fi}

\begin{document} SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15} %SHA-256 is a hash function with a 256-bit long output: \hash{d270f\char"02C6\relax747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}% \char" denoted char syntax not supported \end{document}

Related: How can I make LaTeX to recognize spaces in my macro (catcode 10)?

Solution Using Intercharacter Tokens

\XeTeXinterchartokenstate=1                     % turn them on
\XeTeXinterchartoks 0 0 = {\penalty0\relax}#1}  % use insert token

This is my preferred solution if using TeX Live 2017 and using xelatex. This has the advantage that it supports the original capabilities of \texttt-it should-like denoted characters (see comments under David Carlisle's answer).

\documentclass{article}

\newcommand{\hash}[1]{\texttt{\XeTeXinterchartokenstate=1\XeTeXinterchartoks 0 0 = {\penalty0\relax}#1}}%In a perfect world, this would be changed to allow linebreaks anywhere in #1

\begin{document} SHA-256 is a hash function with a 256-bit long output: \hash{d270f747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15} SHA-256 is a hash function with a 256-bit long output: \hash{d270f\char"02C6\relax747a8743f11aef93c10e9cb6932cc0b862464c1133dc0f8889088740d15}

\end{document}

LeO
  • 1,451
  • I've adapted the initial macro since when using it with text that has space it would add recursively more space. Just in case somebody would like to use this macro. – LeO Jan 18 '24 at 11:59
2

Configure it as a URL. EDITED to do it inside a group as \hexdump{}, so that \url remains unaffected by the redefinitions.

\documentclass{article}
\usepackage{url,lipsum}
\urlstyle{rm}
\newcommand\hexdump[1]{%
  \begingroup\urlstyle{tt}%
  \def\UrlBreaks{%
    \do\1\do\2\do\3\do\4\do\5\do\6\do\7\do\8\do\9\do\0\do\A\do\B\do\C\do\D\do\E\do\F}%
  \url{#1}\endgroup%
}
\textwidth3.34in
\parskip 1ex
\begin{document}
\noindent\hexdump{5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5%
A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC5A0FF349ABC}

\lipsum[1]

URLs should be unaffected: \url{www.xyz.com}
\end{document}

enter image description here

  • Thanks, but I have two small issues with that: though it does the job and listing all the characters is not that long, it still require to do it, and modifies the url command that I use at several other occasions in my document (which, granted, was not specified in my question). – Anab Aug 09 '16 at 18:46
  • @Anab I can (and will) resolve the 2nd issue easily enough. I'm not sure what you mean by the first issue. – Steven B. Segletes Aug 09 '16 at 18:56
  • What I mean is that, compared to David Carlisle's answer, that I accepted, yours require to a long list of \do (line 5) which, though not that hard to do for 16 characters, feels a bit blunt to me. That's however just a feeling and I've done way uglier at several occasions when I couldn't find an elegant solution quickly enough. ;) – Anab Aug 09 '16 at 19:21
  • @Anab I agree David's answer is very elegant. Nonetheless, I have revised to not interfere with underlying \url configuration. – Steven B. Segletes Aug 09 '16 at 19:31
  • 1
    I'm sticking with the accepted answer for its elegance but I like seeing different ways to do stuff so you got my upvote now that it the rest of my document unaffected. – Anab Aug 09 '16 at 19:40