Если ваш вопрос не влез ни в одну из вышеперечисленных тем, вам сюда.
Ответить

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 07:52:32

вот еще вопрос,
есть две вроде бы одинаковые функции:
Код:
procedure AddCheckSumm(var data: array of byte; len: integer);
type trec = record
      t0: byte;
      t1: byte;
      t2: byte;
      t3: byte;
    end;
var chksum: Longword;
    i: integer;
    ecx: Longword;
    t: trec;
begin
  if length(data)<len+4 then exit;
  chksum := 0;
  i := 0;
  while i < len do begin
      t.t0 := data[i];
      t.t1 := data[i + 1];
      t.t2 := data[i + 2];
      t.t3 := data[i + 3];
      ecx := Longword(t);
      chksum := chksum xor ecx;
      i := i + 4;
  end;
  t := trec(chksum);
  data[len]:=t.t0;
  data[len+1]:=t.t1;
  data[len+2]:=t.t2;
  data[len+3]:=t.t3;

и
Код:
void AddCheckSumm(int data[], int len) // expl: AddCheckSumm(Data,24);
{
    union trec
        {
            char t[4];
            long l;
        };
    trec t;

    unsigned long int chksum;
    unsigned long int ecx;
    int i=0;
    //тело.
    if (sizeof(data) < len+4)
    { return; };

    chksum = 0;
    i = 0;

    while (i<len)
        {
            t.t[0] = data[i];
            t.t[1] = data[i +1];
            t.t[2] = data[i +2];
            t.t[3] = data[i +3];

            ecx = t.l;
            chksum = chksum ^ ecx;
            i = i +4;
        }

    t.l = chksum;
    data[len] = t.t[0];
    data[len +1] = t.t[1];
    data[len +2] = t.t[2];
    data[len +3] = t.t[3];
}


только вот первая работает, а вторая - нет. где прокол ?
Последний раз редактировалось Кислый Чт ноя 11, 2010 08:46:37, всего редактировалось 1 раз.

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 08:28:01

вообще-то это не одинаковые функции. в первой на входе массив байтов, а во второй - int-ов, что совсем не одно и то же.

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 09:05:47

тогда энто попа. Ближайший "сосед" это char.. но это в win. А в linux мы используем юникод.
тогда попутный вопрос," как перевести delphi Byte в с\c++ " ?

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 09:08:41

или все-таки можно использовать char ? он правда составляет диапазон -128 .. 128.
или использовать unsigned char ? 0 .. 256

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 09:17:59

если уж вы пишите для разных платформ, так и применяли бы одинаковый инструмент: и там и там С++/С или и там и там Delphi... тогда проблем было бы меньше...

кстати, в Delphi имеется тип WideChar и определенные функции для работы со строками из этих символов - как раз юникодовые...

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 09:32:14

эмм.. то что я начал учиться программировать в ubuntu, это случайная случайность. но мне понравилось ))
а задача перенести код с делфи на си, так чтобы он был предельно похож на оригинал.

так как в данном случае выкрутится ?

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 09:52:33

у вас есть работающая дельфийская программа и данные, которые она правильно обрабатывает в винде, вам надо сделать ее аналог на Си, чтобы данные в линухе обрабатывались точно так же?

тогда вам надо в Сишной программе использовать типы данных, один в один совместимые с дельфийскими. боюсь, что это не тривиальная задача...

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 12:54:48

хмм. не вотру почему сама функция не работает при вызове.

в общем, модифицировал я программу на делфи (добавил запись в файл), получил длину и сам массив:
Код:
length(data) = 40, len = 24
data in   7|156|30|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0    |0 |0|0|0|0|0|0|0|0|0|0|0|0|0|40|
data out 7|156|30|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|7|156|30|0|0|0|0|0|0|0|0|0|0|0|0|0|40|


переделал программу на си:
Код:
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <iostream>

using namespace std;

int main()
{       unsigned char data[] = {7,156,30,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,40}; //data in привел к беззнаковой длиной 1 байт
        int len = 24;
    union trec
        {
            unsigned char t[4];
            long l;
        };
    trec t;

    unsigned long int chksum;
    unsigned long int ecx;
    int i=0;
    //тело.
    if (sizeof(data) < len+4)
    { cout<<"in.пи%%ец"<<endl; };

    chksum = 0;
    i = 0;

    while (i<len)
        {
            t.t[0] = data[i];
            t.t[1] = data[i +1];
            t.t[2] = data[i +2];
            t.t[3] = data[i +3];

            ecx = t.l;
            chksum = chksum ^ ecx;
            i = i +4;
        }

    t.l = chksum;
    data[len] = t.t[0];
    data[len +1] = t.t[1];
    data[len +2] = t.t[2];
    data[len +3] = t.t[3];

    for(i=0;i<41;i++){
    cout << (int)data[i]<<"|";}
    return 0;
}

результат (data out) получился один в один с оригиналом.

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 13:21:09

вот где прокол
Код:
    if (sizeof(data) < len+4)
    { return; };


sizeof(data) всегда равно размеру указателя на вашей архитектуре.

цикл надо делать до len-4 и записывать в data[len-5..1]

лучше писать типы как int *p, char *p и т.д.

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 13:25:13

цикл надо делать до len-4 и записывать в data[len-5..1]


не втёр. для чего и что туда записывать ?

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 13:40:22

тебе надо поболее узнать о массивах в си. как они передаются в функции и т.д.
в частности чтобы твоя функция была универсальной надо передавать указатель на массив с уже нужным размером. в твоем случае нужно передавать массив размеров (размер_данных+размер_crc).

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 13:47:01

вобще, что надо? у меня есть сомнения, в том, что код делает то, что тебе необходимо :)

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 13:53:30

наверно не стоит мучить мозг, а заранее определять длинну массива, и передавать его в функцию.. как вам идея ?

Код:
    ...
    int len_main = 24;
    short len_data_main = sizeof(data_main);
    Add(data_main, len_main, len_data);
    ...


а вместо:
Код:
    if (sizeof(data) < len+4)
    { return; };

Код:
    if (lenData < len+4)
    { return; };


Я вообще сомневаюсь в том что я делаю, но у меня задача просто повторить код максимально близко по читавельности, стилю и результатам.

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 14:07:03

Кислый писал(а):наверно не стоит мучить мозг, а заранее определять длинну массива, и передавать его в функцию.. как вам идея ?


да. так будет правильней. только хочу предостеречь.
Код:
char data[]={1}; char *dt = data; // sizeof(data)=1, sizeof(dt)=4 или 8 в зависимости от архитектуры.


т.е. sizeof работает на уровне языка. она не может знать о размере массива по указателю ей переданному. она возвращает размер объекта. если ей передан массив как в первом случае, то будет размер массива. если указатель, то размер указателя.

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 14:29:21

lix писал(а):sizeof(data) всегда равно размеру указателя на вашей архитектуре.
уверены? по-моему, sizeof(data) покажет размер массива в байтах, если при определении массива он был явно задан:
int data[30];
sizeof(data) == 60;

sizeof отличает массивы от прочих указателей...

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 14:35:47

ARV писал(а):
lix писал(а):sizeof(data) всегда равно размеру указателя на вашей архитектуре.
уверены? по-моему, sizeof(data) покажет размер массива в байтах, если при определении массива он был явно задан:
int data[30];
sizeof(data) == 60;

sizeof отличает массивы от прочих указателей...

согласен. я не уточнил, что написал это для случая его функции с int data[]. data в том случае указатель на int.

Re: помогите с поиском ответа ( C си)

Чт ноя 11, 2010 22:35:37

ладно. эту проблему я уже решил.

теперь, если звезды мне благоприятствуют, не подскажите ли где найти вменяемый мануал по GMP ? мне нужно конкретно rsa.

Код:


Base10StringToFGInt('65537',e);
Base256StringToFGInt(sD,d); // sD - строка которую следует зашифровать,
Base256StringToFGInt(sM,m); // sM - rsa_key
FGIntMontgomeryModExp(d,e,m,r); // само шифрование, результат в r
FGIntToBase256String(r,sR); // преобразование к string;


мне нужно было переписать на си:
Код:
    mpz_t m, e, d, r;
    mpz_init(m);
    mpz_init(e);
    mpz_init(d);
    mpz_init(r);

    mpz_inp_str(d, sD, 16);
    mpz_inp_str(m, sM, 16);
    mpz_inp_str(e, "65537", 10);

    mpz_powm(r, d, e, m);

    mpz_out_str(sR, 16, r);


выдает ошибку
/home/nysha/c++/three/main.cpp|33|error: cannot convert ‘char*’ to ‘FILE*’ for argument ‘2’ to ‘size_t __gmpz_inp_str(__mpz_struct*, FILE*, int)’|


пытаюсь высмотреть что-то в исходниках, но толку мало.

Re: помогите с поиском ответа ( C си)

Пт ноя 12, 2010 09:45:56

ты издеваешься, да? :)
он хочет вторым аргументом дескриптор открытого файла, из которого он будет читать строку с данными. файлы открыть можно при помощи fopen, или указать stdin - в этом случае строку он будет читать со стандартного ввода, т.е. с терминала.

UPD: да. поспешил mpz_init_set_str нужна

Re: помогите с поиском ответа ( C си)

Пт ноя 12, 2010 10:26:30

а что может значить ошибка /home/kisly/c++/RSA/main.cpp|12| undefined reference to `__gmpz_init' |

неопределенная ссылка на __gmpz_init ? почему ?

Re: помогите с поиском ответа ( C си)

Пт ноя 12, 2010 10:35:41

вот тестовая 100% рабочая прога.
из командной строки компилится и запускается
Код:
gcc -Wall -lgmp fab.c -o fab && ./fab


Код:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gmp.h>

int main()
{
   int num=0;
   mpz_t f_1;
   mpz_t f_2;

   mpz_init(f_1);
   mpz_init(f_2);
   mpz_set_ui(f_1,0);
   mpz_set_ui(f_1,111);
   printf("%10d: 0\n",++num);
int i;
   for( i = 0; i<64; i++){
       mpz_add(f_1,f_2,f_1);
       mpz_swap(f_1,f_2);
       char * res = mpz_get_str(NULL,10,f_2);
       printf("%10d: %s\n",++num, res);
       free(res);  }

   mpz_clear(f_1);
   mpz_clear(f_2);
   return 0;
}


в ide выдает эту непонятную ошибку :(
Ответить