简体   繁体   中英

How do I read last n characters of a string in a single file?

I want to read the last n characters of a line in the file "passwordhashes.txt". If "$1$$" is detected in a line, I want to print the last 26 characters of that line and if "$6$$" is detected instead, I want to print the last 90 characters of that line. The following code returns the first 26 characters if md5 is detected and first 90 characters if sha512 is detected but that is not what I want.

#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;
}

A few lines in the passwordhashes.txt (there are a total of 219128 lines in this file so I will just list out a few):

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/

Here is a simple remake of strncpy which is a standard function which copies n characters from a source to a destination. This function copies n characters from the last from src and copy it to dest . if n is greater than the length of src , it does nothing.

#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);
}

Here is a remake of your program using 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM