I’d like to port bcrypt, found here, to Xojo, but I’m afraid my C is just not up to the task, so I thought I’d throw a few specific questions out there to help move it along. I’ll make the final product available when finished.
If there is enough interest, I’ll even throw the project up onto GitHub.
What is an u_int8_t? I get that it’s an UInt8, but what’s the “_t” about? The answer to this will help me understand the parameters and how they are being used.
And does this code ultimately do the same as Xojo’s EncodeBase64?
Except it looks like this function is expecting a single value, and will use it to do calculations, so u_int8_t *buffer is a pointer to a single byte, isn’t it?
I feel like I’m missing something in how C treats these variables.
[quote=60968:@Kem Tekinay]Except it looks like this function is expecting a single value, and will use it to do calculations, so u_int8_t *buffer is a pointer to a single byte, isn’t it?
[/quote]
more like the starting address of a sequence of bytes
the reason I say this is
u_int8_t *bp = buffer;
u_int8_t *p = data;
and subsequently all the ptr math
c1 = *p++;
*bp++ = Base64Code[(c1 >> 2)];
etc
which steps through the byes pointed at by those two ptrs
u_int8_t *buffer
means “a pointer to” and not “a pointer to a single value” so it is something “like” a memory block but you don’t know how big it is the memory area.
u_int16_t len reports how big it is the memory area (up to 65536 bytes in this case)
Thanks. At this point, I’m still renewing my relationship with C. Like an almost-ex, I am being reminded why I didn’t want to get involved in the first place…
Function encode_base64 (ByRef buffer As UInt8, ByRef data As UInt8, thelen As UInt16)
[/quote]
Probably not - I think that the *buffer and *data should be considered “Pointers to an array of values” rather than “Pointers to one single value” so I’d write it as follows:
Function encode_base64 (buffer As MemoryBlock, data As MemoryBlock, thelen As UInt16)
p refers to the pointer itself.
*p points at the pointer’s value.
p++ is to increment the pointer address (moving it to the next part of the array it points to, for example).
*p++ increments the value that the pointer points to.
I wrote this example to hopefully clarify further:
[code]// make an integer array with two elements
int a[2];
a[0] = 0;
a[1] = 0;
// make a pointer
int *p;
// point the pointer to the array’s first element
p = &a[0];
// increase the value of a[0] by 1
*p++;
// print this value
printf("%d
", *p); // 1 is printed
// make p point to a[1]
p++;
// print this value
printf("%d
", *p); // 0 is printed[/code]
With this in mind you can always print the pointer’s address by referring to p. Then when you want to print the pointer’s value you refer to *p.
Thanks Joshua, that was very helpful. Believe it or not, I knew this at one time, but that’s how far removed I’ve become from trying to learn C.
So, with this in mind, I think I’ve translated this code faithfully. (I realize this is not the optimal way to do it in Xojo given its tools, but my goal here is get the closest translation I can get. I’ll optimize later.)
My translation. Does it appear that I’ve gotten this right?
Private Sub encode_base64(buffer As MemoryBlock, data As MemoryBlock)
dim lastByteIndex as integer = data.Size - 1
dim bp, p as integer
dim c1, c2 as byte
while ( p <= lastByteIndex )
c1 = data.Byte( p )
p = p + 1
buffer.Byte( bp ) = Base64Code( Bitwise.ShiftRight( c1, 2 ) )
bp = bp + 1
c1 = Bitwise.ShiftLeft( c1 and &h03, 4 )
if p > lastByteIndex then
buffer.Byte( bp ) = Base64Code( c1 )
exit while
end if
c2 = data.Byte( p )
p = p + 1
c1 = c1 or ( Bitwise.ShiftRight( c2, 4 ) and &h0F )
buffer.Byte( bp ) = Base64Code( c1 )
bp = bp + 1
c1 = Bitwise.ShiftLeft( c2 and &h0F, 2 )
if p > lastByteIndex then
buffer.Byte( bp ) = Base64Code( c1 )
bp = bp + 1
exit while
end if
c2 = data.Byte( p )
p = p + 1
c1 = c1 or ( Bitwise.ShiftLeft( c2, 6 ) and &h03 )
buffer.Byte( bp ) = Base64Code( c1 )
bp = bp + 1
buffer.Byte( bp ) = Base64Code( c2 and &h3F )
bp = bp + 1
wend
buffer.Byte( bp ) = 0
End Sub