array and pointers
Matthew Wesley
mwesley at acm.org
Thu Jan 25 06:34:06 PST 2007
On Thu, 25 Jan 2007 12:36:53 +0100
Alberto <reda at zioale.it> wrote:
> hi, I have just started to play with D, and I have some little
> problem.
>
> In C I did something like:
>
> #define uchar unsigned char
>
> void aes_ecb_decrypt(aes_context *ctx, uchar *input, uchar *output,
> uint len ) {
> int n;
> uchar *pin, *pout;
>
> // test to validate parameters..
>
> n = len;
> pin = input;
> pout = output;
>
> while( n > 0 ) {
> decrypt_block(ctx, pin, pout );
> pin += 16;
> pout += 16;
> n -= 16;
> }
> }
>
> in D:
>
> void decrypt_block(ubyte[] input, ubyte[] output) ;
>
> ubyte[] ecb_decrypt(in ubyte[] input)
> in {
> assert(input.length > 0);
> }
> out(output) {
> assert(output.length == input.length);
> }
> body {
> int i,n, idx;
> ubyte[] pin;
> ubyte[] pout;
> ubyte[] output;
>
> n = input.length;
> output.length = n;
> idx=0;
>
> while( n > 0 ) {
> if (idx+BLOCK_SIZE >= input.length) {
> //we must decrypt less then BLOCK_SIZE
> decrypt_block(input[idx..$],
> output[idx..$]); } else {
> decrypt_block( input[idx..idx+BLOCK_SIZE],
> output[idx..idx+BLOCK_SIZE]); }
> idx += BLOCK_SIZE;
> n -= BLOCK_SIZE;
> }
> return output;
> }
>
> but I don't think that is the right way..
> There is a simpler way using pointers like in C?
> I have tried to use something like:
>
>
> int n;
> ubyte *pin;
> ubyte *pout;
> ubyte[] output;
>
> n = input.length;
> output.length = n;
> pin = input.ptr;
> pout = output.ptr;
>
> while( n > 0 ) {
> decrypt_block(cast(ubyte[])pin, cast(ubyte[])pout);
> pin += 16;
> pout += 16;
> n -= 16;
> }
>
> but I get:
> test_aes.d(158): Error: e2ir: cannot cast from ubyte* to ubyte[]
> test_aes.d(158): Error: e2ir: cannot cast from ubyte* to ubyte[]
>
> yes I can modify decrypt_block, but this is not the point, I want just
> understand how can I solve it, in a D way.
>
>
The problem you are having is that arrays in D are not like arrays in
C. Think of D arrays as:
struct DArray {
type *ptr;
size_t length;
}
This means there is no way to cast from a pointer to a D array, because
D MUST know the length of that array.
Here is my solution to the same ECB problem:
void[] encrypt_ECB(void[] data, void[]to)
in {
assert(data.length > 0);
assert(to is null || to.length >= data.length + pad_length(data));
} out(ciphertext) {
assert(ciphertext.length >= data.length);
assert(ciphertext.length <= data.length +b_size);
assert(ciphertext.length % b_size == 0);
body {
ubyte pad = pad_length(data);
size_t total = data.length + pad;
if(to is null)
to = new ubyte[total];
// copy and pad data
to[0 .. data.length] = data;
to[data.length .. total] = pad;
assert(to.length % b_size == 0);
for(size_t i=0; i < data.length; i += b_size) {
encipher(output[i .. i+b_size]);
}
return to;
}
This is a member function of my BlockCipherAlg abstract class.
Sub-classes of BlockCipherAlg implement encipher(void[]), allowing me
to write one ECB, CBC, PCBC and other chaining method implementations
for all block algorithms. If you're interested, I have a nearly
complete version of my crypto library framework.
--
-----------------------------------------------------
PGP public key ID:
pub 2048R/2C19B7E6 2006-02-19 [expires: 2007-02-19]
uid Matthew Wesley <mwesley at acm.org>
Find it at http://pgp.mit.edu
-----------------------------------------------------
More information about the Digitalmars-d-learn
mailing list