How can I invert bits of an unsigned byte in Java?
Asked Answered
P

8

21

I am trying to write a decoder for a very simple type of encryption. Numbers from 0-255 are entered via Scanner, the bits are inverted, and then converted to a character and printed.

For example, the number 178 should convert to the letter "M".

178 is 10110010.

Inverting all of the bits should give 01001101, which is 77 or "M" as a character.

The main problem I have is that, as far as I can tell, Java does not support unsigned bytes. I could read values as an int or a short, but then the values will be off during the conversion due to the extra bits. Ideally I could just use the bitwise complement operator, but I think I will end up getting negative values if I do this with signed numbers. Any ideas on how I should approach this?

Performative answered 24/7, 2010 at 10:25 Comment(2)
You picked a really bad example, because it allows two readings.Nummary
The bitmask was exactly what I needed - I had no idea you could do that. Very useful. Thank you all for the replies.Performative
C
18

I would simply use the ones complement and get rid of the other bits by using binary and.

public class Conv {
    public static void main(String[] args) {
        int val = 178;
        val = ~val & 0xff;
        System.out.println((char) val);
    }
}
Cowshed answered 24/7, 2010 at 10:42 Comment(0)
N
12
~n & 0xff

~ does the complement and implicitly converts to an integer like all numeric operations do, then & 0xff masks out everything except the lower 8 bits to get the unsigned value, again as an integer.

I first read your question differently, to invert the order instead of the values of the bits, and this was the answer.

You can use Integer.reverse() (untested):

Integer.reverse(n << 24) & 0xff
Nummary answered 24/7, 2010 at 10:42 Comment(2)
If anybody is using this, the Integer.reverse method works perfectly (tested)! Thanks btw!Bomar
Link is broken, correct link is here for Integer.reverse()Alforja
R
6

Bitwise operations in Java are defined for int so it makes sense to work with int rather than byte. You can use Scanner.nextInt, rather than Scanner.nextByte. You should validate the user's input to ensure that all integers entered are in the range 0 to 255 and display an appropriate error message if an out-of-range number is encountered.

Once you have the number stored in an integer then to flip the least significant 8 bits you can XOR with 0xff. This should work as you expect for all inputs between 0 and 255:

x ^= 0xff;

Example:

String input = "178 0 255";
Scanner s = new Scanner(input);
while (s.hasNextInt()) {
    int x = s.nextInt();
    if (x < 0 || x > 255) {
        System.err.println("Not in range 0-255: " + x);
    } else {
        x ^= 0xff;
        System.out.println(x);
    }
}

Result:

77
255
0
Recommendatory answered 24/7, 2010 at 10:39 Comment(2)
This will not work if the value originally is stored in a byte, because then it will be sign-extended to a negative integer.Nummary
@starblue: It appears that he is using a Scanner. I've updated my answer to mention this.Recommendatory
C
3

If Java supports this, you could read it into a larger type, bitwise-compliment, then bit-mask out the unwanted bits.

int x = [your byte];
x = ~x & 0xFF;
Carilla answered 24/7, 2010 at 10:38 Comment(0)
I
0

The easiest way to do this is three stages:

  1. Read the value as an int (32 bits in java). It may read as negative but we only care about the bottom 8 bits anyway. int i = scanner.nextByte();
  2. Do the inversion as an int using bitwise operators (as you say will give you 1s as high order bits: i = ~i;
  3. Lose the high order bits with a logical AND: i = i & 0xFF;

Then just use the result as a character (which is actually 16 bits in java, but we will only use 8 of them):

char c=(char)a;
System.out.println(c); 

All together:

int i = scanner.nextByte(); // change this to nextInt() depending on file format
i = ~i;
i = i & 0xFF;
char c=(char)a;
System.out.println(c); 
Isabellaisabelle answered 24/7, 2010 at 10:38 Comment(1)
In the question it says "Numbers from 0-255". scanner.nextByte will fail for numbers greater than 127.Recommendatory
W
0

Or, you can do it without any dodgy signed arithmetic, using string handling instead:-

public class ReverseBits {
public static void main(String[] args) {

    byte[] reversedBits = {
            (byte) 0b00000000,
            (byte) 0b10000000,
            (byte) 0b01000000,
            (byte) 0b11000000,
            (byte) 0b00100000,
            (byte) 0b10100000,
            (byte) 0b01100000,
            (byte) 0b11100000,
            (byte) 0b00010000,
            (byte) 0b10010000,
            (byte) 0b01010000,
            (byte) 0b11010000,
            (byte) 0b00110000,
            (byte) 0b10110000,
            (byte) 0b01110000,
            (byte) 0b11110000,
            (byte) 0b00001000,
            (byte) 0b10001000,
            (byte) 0b01001000,
            (byte) 0b11001000,
            (byte) 0b00101000,
            (byte) 0b10101000,
            (byte) 0b01101000,
            (byte) 0b11101000,
            (byte) 0b00011000,
            (byte) 0b10011000,
            (byte) 0b01011000,
            (byte) 0b11011000,
            (byte) 0b00111000,
            (byte) 0b10111000,
            (byte) 0b01111000,
            (byte) 0b11111000,
            (byte) 0b00000100,
            (byte) 0b10000100,
            (byte) 0b01000100,
            (byte) 0b11000100,
            (byte) 0b00100100,
            (byte) 0b10100100,
            (byte) 0b01100100,
            (byte) 0b11100100,
            (byte) 0b00010100,
            (byte) 0b10010100,
            (byte) 0b01010100,
            (byte) 0b11010100,
            (byte) 0b00110100,
            (byte) 0b10110100,
            (byte) 0b01110100,
            (byte) 0b11110100,
            (byte) 0b00001100,
            (byte) 0b10001100,
            (byte) 0b01001100,
            (byte) 0b11001100,
            (byte) 0b00101100,
            (byte) 0b10101100,
            (byte) 0b01101100,
            (byte) 0b11101100,
            (byte) 0b00011100,
            (byte) 0b10011100,
            (byte) 0b01011100,
            (byte) 0b11011100,
            (byte) 0b00111100,
            (byte) 0b10111100,
            (byte) 0b01111100,
            (byte) 0b11111100,
            (byte) 0b00000010,
            (byte) 0b10000010,
            (byte) 0b01000010,
            (byte) 0b11000010,
            (byte) 0b00100010,
            (byte) 0b10100010,
            (byte) 0b01100010,
            (byte) 0b11100010,
            (byte) 0b00010010,
            (byte) 0b10010010,
            (byte) 0b01010010,
            (byte) 0b11010010,
            (byte) 0b00110010,
            (byte) 0b10110010,
            (byte) 0b01110010,
            (byte) 0b11110010,
            (byte) 0b00001010,
            (byte) 0b10001010,
            (byte) 0b01001010,
            (byte) 0b11001010,
            (byte) 0b00101010,
            (byte) 0b10101010,
            (byte) 0b01101010,
            (byte) 0b11101010,
            (byte) 0b00011010,
            (byte) 0b10011010,
            (byte) 0b01011010,
            (byte) 0b11011010,
            (byte) 0b00111010,
            (byte) 0b10111010,
            (byte) 0b01111010,
            (byte) 0b11111010,
            (byte) 0b00000110,
            (byte) 0b10000110,
            (byte) 0b01000110,
            (byte) 0b11000110,
            (byte) 0b00100110,
            (byte) 0b10100110,
            (byte) 0b01100110,
            (byte) 0b11100110,
            (byte) 0b00010110,
            (byte) 0b10010110,
            (byte) 0b01010110,
            (byte) 0b11010110,
            (byte) 0b00110110,
            (byte) 0b10110110,
            (byte) 0b01110110,
            (byte) 0b11110110,
            (byte) 0b00001110,
            (byte) 0b10001110,
            (byte) 0b01001110,
            (byte) 0b11001110,
            (byte) 0b00101110,
            (byte) 0b10101110,
            (byte) 0b01101110,
            (byte) 0b11101110,
            (byte) 0b00011110,
            (byte) 0b10011110,
            (byte) 0b01011110,
            (byte) 0b11011110,
            (byte) 0b00111110,
            (byte) 0b10111110,
            (byte) 0b01111110,
            (byte) 0b11111110,
            (byte) 0b00000001,
            (byte) 0b10000001,
            (byte) 0b01000001,
            (byte) 0b11000001,
            (byte) 0b00100001,
            (byte) 0b10100001,
            (byte) 0b01100001,
            (byte) 0b11100001,
            (byte) 0b00010001,
            (byte) 0b10010001,
            (byte) 0b01010001,
            (byte) 0b11010001,
            (byte) 0b00110001,
            (byte) 0b10110001,
            (byte) 0b01110001,
            (byte) 0b11110001,
            (byte) 0b00001001,
            (byte) 0b10001001,
            (byte) 0b01001001,
            (byte) 0b11001001,
            (byte) 0b00101001,
            (byte) 0b10101001,
            (byte) 0b01101001,
            (byte) 0b11101001,
            (byte) 0b00011001,
            (byte) 0b10011001,
            (byte) 0b01011001,
            (byte) 0b11011001,
            (byte) 0b00111001,
            (byte) 0b10111001,
            (byte) 0b01111001,
            (byte) 0b11111001,
            (byte) 0b00000101,
            (byte) 0b10000101,
            (byte) 0b01000101,
            (byte) 0b11000101,
            (byte) 0b00100101,
            (byte) 0b10100101,
            (byte) 0b01100101,
            (byte) 0b11100101,
            (byte) 0b00010101,
            (byte) 0b10010101,
            (byte) 0b01010101,
            (byte) 0b11010101,
            (byte) 0b00110101,
            (byte) 0b10110101,
            (byte) 0b01110101,
            (byte) 0b11110101,
            (byte) 0b00001101,
            (byte) 0b10001101,
            (byte) 0b01001101,
            (byte) 0b11001101,
            (byte) 0b00101101,
            (byte) 0b10101101,
            (byte) 0b01101101,
            (byte) 0b11101101,
            (byte) 0b00011101,
            (byte) 0b10011101,
            (byte) 0b01011101,
            (byte) 0b11011101,
            (byte) 0b00111101,
            (byte) 0b10111101,
            (byte) 0b01111101,
            (byte) 0b11111101,
            (byte) 0b00000011,
            (byte) 0b10000011,
            (byte) 0b01000011,
            (byte) 0b11000011,
            (byte) 0b00100011,
            (byte) 0b10100011,
            (byte) 0b01100011,
            (byte) 0b11100011,
            (byte) 0b00010011,
            (byte) 0b10010011,
            (byte) 0b01010011,
            (byte) 0b11010011,
            (byte) 0b00110011,
            (byte) 0b10110011,
            (byte) 0b01110011,
            (byte) 0b11110011,
            (byte) 0b00001011,
            (byte) 0b10001011,
            (byte) 0b01001011,
            (byte) 0b11001011,
            (byte) 0b00101011,
            (byte) 0b10101011,
            (byte) 0b01101011,
            (byte) 0b11101011,
            (byte) 0b00011011,
            (byte) 0b10011011,
            (byte) 0b01011011,
            (byte) 0b11011011,
            (byte) 0b00111011,
            (byte) 0b10111011,
            (byte) 0b01111011,
            (byte) 0b11111011,
            (byte) 0b00000111,
            (byte) 0b10000111,
            (byte) 0b01000111,
            (byte) 0b11000111,
            (byte) 0b00100111,
            (byte) 0b10100111,
            (byte) 0b01100111,
            (byte) 0b11100111,
            (byte) 0b00010111,
            (byte) 0b10010111,
            (byte) 0b01010111,
            (byte) 0b11010111,
            (byte) 0b00110111,
            (byte) 0b10110111,
            (byte) 0b01110111,
            (byte) 0b11110111,
            (byte) 0b00001111,
            (byte) 0b10001111,
            (byte) 0b01001111,
            (byte) 0b11001111,
            (byte) 0b00101111,
            (byte) 0b10101111,
            (byte) 0b01101111,
            (byte) 0b11101111,
            (byte) 0b00011111,
            (byte) 0b10011111,
            (byte) 0b01011111,
            (byte) 0b11011111,
            (byte) 0b00111111,
            (byte) 0b10111111,
            (byte) 0b01111111,
            (byte) 0b11111111
             };




for (var i = 0; i < 256; i++) {
        var b = (byte) i;
        var s = String.format("%8s", Integer.toBinaryString(b & 0xFF)).replace(' ', '0');
        var reversedString = new StringBuilder();
        reversedString.append(s);
        reversedString = reversedString.reverse();
        var sR = reversedString.toString();
        System.out.println(i + ", " + s + ", " + sR + ", " + (byte) i + ", " + reversedBits[i]);
    }

which produces:-

0, 00000000, 00000000, 0, 0
1, 00000001, 10000000, 1, -128
2, 00000010, 01000000, 2, 64
3, 00000011, 11000000, 3, -64
4, 00000100, 00100000, 4, 32
5, 00000101, 10100000, 5, -96
6, 00000110, 01100000, 6, 96
7, 00000111, 11100000, 7, -32
8, 00001000, 00010000, 8, 16
9, 00001001, 10010000, 9, -112
10, 00001010, 01010000, 10, 80
11, 00001011, 11010000, 11, -48
12, 00001100, 00110000, 12, 48
13, 00001101, 10110000, 13, -80
14, 00001110, 01110000, 14, 112
15, 00001111, 11110000, 15, -16
16, 00010000, 00001000, 16, 8
17, 00010001, 10001000, 17, -120
18, 00010010, 01001000, 18, 72
19, 00010011, 11001000, 19, -56
20, 00010100, 00101000, 20, 40
21, 00010101, 10101000, 21, -88
22, 00010110, 01101000, 22, 104
23, 00010111, 11101000, 23, -24
24, 00011000, 00011000, 24, 24
25, 00011001, 10011000, 25, -104
26, 00011010, 01011000, 26, 88
27, 00011011, 11011000, 27, -40
28, 00011100, 00111000, 28, 56
29, 00011101, 10111000, 29, -72
30, 00011110, 01111000, 30, 120
31, 00011111, 11111000, 31, -8
32, 00100000, 00000100, 32, 4
33, 00100001, 10000100, 33, -124
34, 00100010, 01000100, 34, 68
35, 00100011, 11000100, 35, -60
36, 00100100, 00100100, 36, 36
37, 00100101, 10100100, 37, -92
38, 00100110, 01100100, 38, 100
39, 00100111, 11100100, 39, -28
40, 00101000, 00010100, 40, 20
41, 00101001, 10010100, 41, -108
42, 00101010, 01010100, 42, 84
43, 00101011, 11010100, 43, -44
44, 00101100, 00110100, 44, 52
45, 00101101, 10110100, 45, -76
46, 00101110, 01110100, 46, 116
47, 00101111, 11110100, 47, -12
48, 00110000, 00001100, 48, 12
49, 00110001, 10001100, 49, -116
50, 00110010, 01001100, 50, 76
51, 00110011, 11001100, 51, -52
52, 00110100, 00101100, 52, 44
53, 00110101, 10101100, 53, -84
54, 00110110, 01101100, 54, 108
55, 00110111, 11101100, 55, -20
56, 00111000, 00011100, 56, 28
57, 00111001, 10011100, 57, -100
58, 00111010, 01011100, 58, 92
59, 00111011, 11011100, 59, -36
60, 00111100, 00111100, 60, 60
61, 00111101, 10111100, 61, -68
62, 00111110, 01111100, 62, 124
63, 00111111, 11111100, 63, -4
64, 01000000, 00000010, 64, 2
65, 01000001, 10000010, 65, -126
66, 01000010, 01000010, 66, 66
67, 01000011, 11000010, 67, -62
68, 01000100, 00100010, 68, 34
69, 01000101, 10100010, 69, -94
70, 01000110, 01100010, 70, 98
71, 01000111, 11100010, 71, -30
72, 01001000, 00010010, 72, 18
73, 01001001, 10010010, 73, -110
74, 01001010, 01010010, 74, 82
75, 01001011, 11010010, 75, -46
76, 01001100, 00110010, 76, 50
77, 01001101, 10110010, 77, -78
78, 01001110, 01110010, 78, 114
79, 01001111, 11110010, 79, -14
80, 01010000, 00001010, 80, 10
81, 01010001, 10001010, 81, -118
82, 01010010, 01001010, 82, 74
83, 01010011, 11001010, 83, -54
84, 01010100, 00101010, 84, 42
85, 01010101, 10101010, 85, -86
86, 01010110, 01101010, 86, 106
87, 01010111, 11101010, 87, -22
88, 01011000, 00011010, 88, 26
89, 01011001, 10011010, 89, -102
90, 01011010, 01011010, 90, 90
91, 01011011, 11011010, 91, -38
92, 01011100, 00111010, 92, 58
93, 01011101, 10111010, 93, -70
94, 01011110, 01111010, 94, 122
95, 01011111, 11111010, 95, -6
96, 01100000, 00000110, 96, 6
97, 01100001, 10000110, 97, -122
98, 01100010, 01000110, 98, 70
99, 01100011, 11000110, 99, -58
100, 01100100, 00100110, 100, 38
101, 01100101, 10100110, 101, -90
102, 01100110, 01100110, 102, 102
103, 01100111, 11100110, 103, -26
104, 01101000, 00010110, 104, 22
105, 01101001, 10010110, 105, -106
106, 01101010, 01010110, 106, 86
107, 01101011, 11010110, 107, -42
108, 01101100, 00110110, 108, 54
109, 01101101, 10110110, 109, -74
110, 01101110, 01110110, 110, 118
111, 01101111, 11110110, 111, -10
112, 01110000, 00001110, 112, 14
113, 01110001, 10001110, 113, -114
114, 01110010, 01001110, 114, 78
115, 01110011, 11001110, 115, -50
116, 01110100, 00101110, 116, 46
117, 01110101, 10101110, 117, -82
118, 01110110, 01101110, 118, 110
119, 01110111, 11101110, 119, -18
120, 01111000, 00011110, 120, 30
121, 01111001, 10011110, 121, -98
122, 01111010, 01011110, 122, 94
123, 01111011, 11011110, 123, -34
124, 01111100, 00111110, 124, 62
125, 01111101, 10111110, 125, -66
126, 01111110, 01111110, 126, 126
127, 01111111, 11111110, 127, -2
128, 10000000, 00000001, -128, 1
129, 10000001, 10000001, -127, -127
130, 10000010, 01000001, -126, 65
131, 10000011, 11000001, -125, -63
132, 10000100, 00100001, -124, 33
133, 10000101, 10100001, -123, -95
134, 10000110, 01100001, -122, 97
135, 10000111, 11100001, -121, -31
136, 10001000, 00010001, -120, 17
137, 10001001, 10010001, -119, -111
138, 10001010, 01010001, -118, 81
139, 10001011, 11010001, -117, -47
140, 10001100, 00110001, -116, 49
141, 10001101, 10110001, -115, -79
142, 10001110, 01110001, -114, 113
143, 10001111, 11110001, -113, -15
144, 10010000, 00001001, -112, 9
145, 10010001, 10001001, -111, -119
146, 10010010, 01001001, -110, 73
147, 10010011, 11001001, -109, -55
148, 10010100, 00101001, -108, 41
149, 10010101, 10101001, -107, -87
150, 10010110, 01101001, -106, 105
151, 10010111, 11101001, -105, -23
152, 10011000, 00011001, -104, 25
153, 10011001, 10011001, -103, -103
154, 10011010, 01011001, -102, 89
155, 10011011, 11011001, -101, -39
156, 10011100, 00111001, -100, 57
157, 10011101, 10111001, -99, -71
158, 10011110, 01111001, -98, 121
159, 10011111, 11111001, -97, -7
160, 10100000, 00000101, -96, 5
161, 10100001, 10000101, -95, -123
162, 10100010, 01000101, -94, 69
163, 10100011, 11000101, -93, -59
164, 10100100, 00100101, -92, 37
165, 10100101, 10100101, -91, -91
166, 10100110, 01100101, -90, 101
167, 10100111, 11100101, -89, -27
168, 10101000, 00010101, -88, 21
169, 10101001, 10010101, -87, -107
170, 10101010, 01010101, -86, 85
171, 10101011, 11010101, -85, -43
172, 10101100, 00110101, -84, 53
173, 10101101, 10110101, -83, -75
174, 10101110, 01110101, -82, 117
175, 10101111, 11110101, -81, -11
176, 10110000, 00001101, -80, 13
177, 10110001, 10001101, -79, -115
178, 10110010, 01001101, -78, 77
179, 10110011, 11001101, -77, -51
180, 10110100, 00101101, -76, 45
181, 10110101, 10101101, -75, -83
182, 10110110, 01101101, -74, 109
183, 10110111, 11101101, -73, -19
184, 10111000, 00011101, -72, 29
185, 10111001, 10011101, -71, -99
186, 10111010, 01011101, -70, 93
187, 10111011, 11011101, -69, -35
188, 10111100, 00111101, -68, 61
189, 10111101, 10111101, -67, -67
190, 10111110, 01111101, -66, 125
191, 10111111, 11111101, -65, -3
192, 11000000, 00000011, -64, 3
193, 11000001, 10000011, -63, -125
194, 11000010, 01000011, -62, 67
195, 11000011, 11000011, -61, -61
196, 11000100, 00100011, -60, 35
197, 11000101, 10100011, -59, -93
198, 11000110, 01100011, -58, 99
199, 11000111, 11100011, -57, -29
200, 11001000, 00010011, -56, 19
201, 11001001, 10010011, -55, -109
202, 11001010, 01010011, -54, 83
203, 11001011, 11010011, -53, -45
204, 11001100, 00110011, -52, 51
205, 11001101, 10110011, -51, -77
206, 11001110, 01110011, -50, 115
207, 11001111, 11110011, -49, -13
208, 11010000, 00001011, -48, 11
209, 11010001, 10001011, -47, -117
210, 11010010, 01001011, -46, 75
211, 11010011, 11001011, -45, -53
212, 11010100, 00101011, -44, 43
213, 11010101, 10101011, -43, -85
214, 11010110, 01101011, -42, 107
215, 11010111, 11101011, -41, -21
216, 11011000, 00011011, -40, 27
217, 11011001, 10011011, -39, -101
218, 11011010, 01011011, -38, 91
219, 11011011, 11011011, -37, -37
220, 11011100, 00111011, -36, 59
221, 11011101, 10111011, -35, -69
222, 11011110, 01111011, -34, 123
223, 11011111, 11111011, -33, -5
224, 11100000, 00000111, -32, 7
225, 11100001, 10000111, -31, -121
226, 11100010, 01000111, -30, 71
227, 11100011, 11000111, -29, -57
228, 11100100, 00100111, -28, 39
229, 11100101, 10100111, -27, -89
230, 11100110, 01100111, -26, 103
231, 11100111, 11100111, -25, -25
232, 11101000, 00010111, -24, 23
233, 11101001, 10010111, -23, -105
234, 11101010, 01010111, -22, 87
235, 11101011, 11010111, -21, -41
236, 11101100, 00110111, -20, 55
237, 11101101, 10110111, -19, -73
238, 11101110, 01110111, -18, 119
239, 11101111, 11110111, -17, -9
240, 11110000, 00001111, -16, 15
241, 11110001, 10001111, -15, -113
242, 11110010, 01001111, -14, 79
243, 11110011, 11001111, -13, -49
244, 11110100, 00101111, -12, 47
245, 11110101, 10101111, -11, -81
246, 11110110, 01101111, -10, 111
247, 11110111, 11101111, -9, -17
248, 11111000, 00011111, -8, 31
249, 11111001, 10011111, -7, -97
250, 11111010, 01011111, -6, 95
251, 11111011, 11011111, -5, -33
252, 11111100, 00111111, -4, 63
253, 11111101, 10111111, -3, -65
254, 11111110, 01111111, -2, 127
255, 11111111, 11111111, -1, -1

and which you can see is correct via inspection. Especially around the +/- 127/128 boundary where some of the other answers are wrong.


Just who on God's good Earth decided to have signed bytes in Java? That really was the first Evil.

Whited answered 11/11, 2023 at 13:23 Comment(0)
H
-1

Here are Java bytes, sorted by binary representation (from 00000000 to 11111111):

0, 1, 2, .., 126, 127, -128, -127, .., -2, -1

00000000 is 0, 11111111 is -1

Inverted 0 is -1, inverted 1 is -2, ..., inverted 127 is -128. Thus if you want to invert bits of Java byte you should get your byte with opposite sign and subtract one:

byte myByte = 123;
byte myInvertedByte = -myByte-1;
Hodeida answered 26/1, 2012 at 15:14 Comment(0)
A
-2
private byte reverseBitsByte(byte x)
{
    int intSize = 8;

    byte y = 0;
    for (int position = intSize - 1; position >= 0; position--)
    {
        y += ((x & 1) << position);
        x >>= 1;
    }
    return y;
}
Aristarchus answered 8/7, 2014 at 17:53 Comment(2)
Some explanation would be really nice.Martinamartindale
You should explain what is happening hereMetsky

© 2022 - 2024 — McMap. All rights reserved.