c - 如何读取单个文件中字符串的最后 n 个字符?

标签 c arrays char fgets

我想读取文件“passwordhashes.txt”中一行的最后 n 个字符。如果在一行中检测到“$1$$”,我想打印该行的最后 26 个字符,如果检测到“$6$$”,我想打印该行的最后 90 个字符。如果检测到 md5,则以下代码返回前 26 个字符;如果检测到 sha512,则返回前 90 个字符,但这不是我想要的。

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <strings.h>

int printDataError()
{      
  printf("Data error: Invalid entry found (Skipped)\n");
}    

int main(void)
{
  char buf[1024];
  char **arr2 = NULL;
  int size2 = 0;
  FILE *f2;
  f2 = fopen("passwordhashes.txt", "r");

  while(fgets(buf, 1024, f2)) {
    size2++;
    arr2 = realloc(arr2, sizeof(char*) * size2);
    arr2[size2 - 1] = strdup(buf);
  }

  char line[1000];
  char hash[1000];      
  char md5[5]= "$1$$";
  char sha512[5]="$6$$";
  char *ret;
  char *ret2;

  // Read file line by line     
  for(int j = 0; j < size2; j++) {      
    memset(hash, '\0', sizeof(hash));
    strcpy(line, arr2[j]);

    // Search for md5 
    md5[4]='\0';
    ret = strstr(line, md5);

    // Search for sha512
    sha512[4]='\0';
    ret2 = strstr(line, sha512);

    if (ret) {
      strncpy(hash, line,26);     
      printf("Line %d hash: %s\n", j+1,hash);
    } else if (ret2) {
      strncpy(hash, line,90);    
      printf("Line %d hash: %s\n", j+1,hash);    
    } else {
      printDataError();
    }
  }
  return 0;
}

passwordhashes.txt中的几行(这个文件总共有219128行,所以我只列出几行):

a:$1$$Ij31LCAysPM23KuPlm1wA/
a:$6$$ek/ucQg0IM8SQLyD2D66mpoW0vAF26eA0/pqoN95V.F0nZh1IFuENNo0OikacRkDBk5frNqziMYMdVVrQ0o.51
aah:$1$$bh5o1cAKfH43fc/B1.AjF0
aah:$6$$jdxDww2LkNSlQPmWe5iDRAoBBT5IXa9241nN2bcm2Aukdrr4iH27Y6dj801MjLFaDQxbDBNxY4jvlXdIemiCY/
aahed:$1$$zA2Ef92JR9W7kqAf8Km5B0
aahed:$6$$mYQU7f3NL9Dysccvwv2BAyiCb/gxh9lN1gGnC9sa2uwHGX9VVb7jp3b7u/EZbdObqWrRFgiOLcRn7PEW1cOcz.
aahing:$1$$lDHqezDzqgN4GXlWys7LB0
aahing:$6$$rqJD4oAdyTJ3EasAFN.FeNwTFiCIIklFEo2YcxSS1X5Vutrlqu7r91c4G0PnsVAISIUIBX9.d.8riuVMmKddy/

最佳答案

这里是 strncpy 的简单改造,它是一个标准函数,可以将 n 个字符从源复制到目标。 此函数从src 中的最后一个复制n 个字符并将其复制到dest。如果 n 大于 src 的长度,它什么都不做。

#include <string.h>
void strlncpy(char *dest , char *src , size_t n){
    size_t len = 0;
    if(!dest || !src || (len = strlen(src)) < n)
            return;
    char *p = src + (len - n);
    strcpy(dest , p);
}

这是使用 strlncpy 重制的程序,

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define DELIM ':'
#define MD5_SIGN "$1$$"
#define SHA512_SIGN "$6$$"
#define MD5_LEN 22 /* I changed this to get only the hash. */
#define SHA512_LEN 86

void strlncpy(char *dest , const char *src , size_t n){
    size_t len = 0;
    if(!dest || !src || (len = strlen(src)) < n)
            return;
    char *p = src + (len - n);
    strcpy(dest , p);
}

int main(){
ssize_t r = 0;
size_t n =0;
char *o = NULL , *p  = NULL , hash[100];
FILE *fp = NULL;
if((fp = fopen("passwordhash.txt", "r")) == NULL){
    printf("cannot open file!\n");
    return -1;
}
while((r = getline(&o , &n , fp)) != -1){
        p = o;
        /* Print the raw text. */
        printf("RAW TEXT:: ");
        while(*p != DELIM){
                putchar(*p);
                ++p;
        }
        putchar('\n');
        p = o; 
        if(strstr(p , MD5_SIGN)){
                /* plus one is for the newline. */
                strlncpy(hash , p , MD5_LEN + 1);
                hash[strlen(hash)-1] = '\0'; /* remove newline. */
                printf("MD5 HASH:: %s\n" , hash); 
        }else if(strstr(p , SHA512_SIGN)){
                strlncpy(hash , p , SHA512_LEN + 1);
                hash[strlen(hash)-1] = '\0'; 
                printf("SHA512 HASH:: %s\n" , hash);
        }
}
fclose(fp); // Also close files!
return 0;
}

关于c - 如何读取单个文件中字符串的最后 n 个字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47966908/

相关文章:

使用 char 的 realloc 的 C 动态分配**

c++ - 如何使用 char 数据类型作为数字而不是字符?

c++ - 将对象转换为 char,然后转换为 "uncasting it back"

c - typedef 何时成为实际类型?

javascript - 使用 javascript 和 jquery 连接数组

c++ - 将文本文件快速转换为数组 C++

C:怪串现象

c - sem_wait() 上的总线错误

c - 重新分配,字符**,段错误

c - 根据C中char的值分配char数组