public static String convertMaskedValueToHexString(long msk, long val, int n, boolean truncate,
			int spaceevery, String spacer) {
		StringBuilder sb = new StringBuilder(n * 4);
		int shamt = (n * 4 - 4);
		final long LEFT_NIBBLE = 0x0fL << shamt;
		final long LEFT_BIT = 0x08L << shamt;

		for (int i = 0; i < n; i++) {
			if (!truncate && spaceevery != 0 && i != 0 && i % spaceevery == 0) {
				sb.append(spacer);
			}
			long m = msk & LEFT_NIBBLE;
			if (m == 0L) { // fully-undefined nibble: either truncate or append X
				msk <<= 4;
				val <<= 4;
				if (truncate) {
					continue;
				}
				sb.append('X');
			}
			else if (m == LEFT_NIBBLE) { // fully-defined nibble: append hex digit
				sb.append(String.format("%1X", (val & LEFT_NIBBLE) >>> shamt));
				msk <<= 4;
				val <<= 4;
			}
			else { // partially-defined nibble: append bracketed bits
				sb.append('[');
				for (int j = 0; j < 4; j++) {
					if ((msk & LEFT_BIT) == 0) {
						sb.append('x');
					}
					else if ((val & LEFT_BIT) == 0) {
						sb.append('0');
					}
					else {
						sb.append('1');
					}
					msk <<= 1;
					val <<= 1;
				}
				sb.append(']');
			}
			truncate = false;
		}
		if (sb.length() == 0 && n != 0) {
			return "X";
		}
		return sb.toString();
	}
Convert a masked value into a hexadecimal-ish string.

Converts the data to hexadecimal, placing an X where a nibble is unknown. Where a nibble is
partially defined, it is displayed as four bits in brackets []. Bits are displayed as x, or
the defined value.

For example, consider the mask 00001111:01011100, and the value 00001001:00011000. This will
display as {@code X8:[x0x1][10xx]}. To see the correlation, consider the table:
<table>
<tr>
<th>Display</th>
<th>{@code X}</th>
<th>{@code 8}</th>
<th>{@code :}</th>
<th>{@code [x0x1]}</th>
<th>{@code [10xx]}</th>
</tr>
<tr>
<th>Mask</th>
<td>{@code 0000}</td>
<td>{@code 1111}</td>
<td>{@code :}</td>
<td>{@code 0101}</td>
<td>{@code 1100}</td>
</tr>
<tr>
<th>Value</th>
<td>{@code 0000}</td>
<td>{@code 1000}</td>
<td>{@code :}</td>
<td>{@code 0001}</td>
<td>{@code 1000}</td>
</tr>
</table>

@param msk the mask
@param val the value
@param n the number of nibbles, starting at the right. The example uses 4.
@param truncate true if leading Xs may be truncated. The example uses {@code false}.
@param spaceevery how many nibbles in spaced groups, 0 for no spaces. The example uses 2.
@param spacer the group separator, if applicable. The example uses {@code ':'}.
@return the string representation

@see #convertMaskToHexString(long, int, boolean, int, String)
@see #convertHexStringToMaskedValue(AtomicLong, AtomicLong, String, int, int, String)
Ghidra/Framework/Generic/src/main/java/ghidra/util/NumericUtilities.java