user: Converte this assembly snippet into its equivalent C code:

```asm
<MD5_Binary>:
  endbr64
  push   %r15
  push   %r14
  push   %r13
  push   %r12
  push   %rbp
  push   %rbx
  mov    %rdi,%rbx
  sub    $0x88,%rsp
  mov    %esi,0x18(%rsp)
  mov    %rdx,0x8(%rsp)
  mov    %fs:0x28,%rax
  mov    %rax,0x78(%rsp)
  movabs $0xefcdab8967452301,%rax
  mov    %rax,0x20(%rsp)
  movabs $0x1032547698badcfe,%rax
  mov    %rax,0x28(%rsp)
  cmp    $0x3f,%esi
  jle    L111
  lea    -0x40(%rsi),%ebp
  lea    0x20(%rsp),%r12
  shr    $0x6,%ebp
  lea    0x2c(%rsp),%r14
  lea    0x28(%rsp),%r15
  add    $0x1,%ebp
  lea    0x24(%rsp),%r13
  shl    $0x6,%rbp
  add    %rdi,%rbp
  nopw   0x0(%rax,%rax,1)
L86:
  mov    %rbx,%rdi
  mov    %r14,%r8
  mov    %r15,%rcx
  mov    %r13,%rdx
  mov    %r12,%rsi
  xor    %eax,%eax
  add    $0x40,%rbx
  call   <MD5_Round_Calculate@plt>
  cmp    %rbp,%rbx
  jne    L86
L141:
  mov    0x18(%rsp),%r9d
  lea    0x30(%rsp),%rbx
  mov    %rbp,%rsi
  mov    %rbx,%rdi
  and    $0x3f,%r9d
  mov    %r9d,%edx
  mov    %r9d,0x1c(%rsp)
  mov    %rdx,0x10(%rsp)
  call   <strncpy@plt>
  mov    0x1c(%rsp),%r9d
  mov    0x10(%rsp),%rdx
  xor    %r10d,%r10d
  mov    $0x40,%eax
  sub    %r9d,%eax
  lea    (%rbx,%rdx,1),%rsi
  cmp    $0x8,%eax
  jae    L6
  test   $0x4,%al
  jne    L5
  test   %eax,%eax
  je     L116
  movb   $0x0,(%rsi)
  test   $0x2,%al
  jne    L61
L116:
  orb    $0x80,0x30(%rsp,%rdx,1)
  cmp    $0x37,%r9d
  jbe    L157
  mov    %r14,%r8
  mov    %r15,%rcx
  mov    %r13,%rdx
  mov    %r12,%rsi
  mov    %rbx,%rdi
  xor    %eax,%eax
  call   <MD5_Round_Calculate@plt>
  pxor   %xmm0,%xmm0
  movq   $0x0,0x60(%rsp)
  movaps %xmm0,0x30(%rsp)
  movaps %xmm0,0x40(%rsp)
  movaps %xmm0,0x50(%rsp)
L157:
  mov    0x18(%rsp),%ecx
  lea    0x0(,%rcx,8),%eax
  mov    %eax,0x68(%rsp)
  cmp    $0x1fffffff,%ecx
  jbe    L49
  lea    0x8(,%rcx,8),%eax
  mov    %eax,0x6c(%rsp)
L92:
  mov    %r14,%r8
  mov    %r15,%rcx
  mov    %r13,%rdx
  mov    %r12,%rsi
  mov    %rbx,%rdi
  xor    %eax,%eax
  call   <MD5_Round_Calculate@plt>
  mov    0x8(%rsp),%rax
  movdqa 0x20(%rsp),%xmm1
  movups %xmm1,(%rax)
  mov    0x78(%rsp),%rax
  sub    %fs:0x28,%rax
  jne    L51
  add    $0x88,%rsp
  pop    %rbx
  pop    %rbp
  pop    %r12
  pop    %r13
  pop    %r14
  pop    %r15
  ret
  nopl   0x0(%rax,%rax,1)
L6:
  mov    %eax,%edi
  movq   $0x0,(%rsi)
  movq   $0x0,-0x8(%rsi,%rdi,1)
  lea    0x8(%rsi),%rdi
  and    $0xfffffffffffffff8,%rdi
  sub    %rdi,%rsi
  add    %esi,%eax
  and    $0xfffffff8,%eax
  cmp    $0x8,%eax
  jb     L116
  and    $0xfffffff8,%eax
  xor    %esi,%esi
L2:
  mov    %esi,%r11d
  add    $0x8,%esi
  mov    %r10,(%rdi,%r11,1)
  cmp    %eax,%esi
  jb     L2
  jmp    L116
  nopl   0x0(%rax,%rax,1)
L49:
  movl   $0x0,0x6c(%rsp)
  jmp    L92
L5:
  movl   $0x0,(%rsi)
  movl   $0x0,-0x4(%rsi,%rax,1)
  jmp    L116
  nopl   0x0(%rax,%rax,1)
L111:
  mov    %rdi,%rbp
  lea    0x20(%rsp),%r12
  lea    0x2c(%rsp),%r14
  lea    0x28(%rsp),%r15
  lea    0x24(%rsp),%r13
  jmp    L141
L61:
  xor    %ecx,%ecx
  mov    %cx,-0x2(%rsi,%rax,1)
  jmp    L116
L51:
  call   <__stack_chk_fail@plt>
```

assistant: ```c
void MD5_Binary(const char *string, int len, char *output) {
  unsigned char padding_message[64];
  unsigned char *pstring;
  unsigned int string_byte_len;
  unsigned int string_bit_len;
  unsigned int copy_len;
  unsigned int msg_digest[4];
  unsigned int *A = &msg_digest[0];
  unsigned int *B = &msg_digest[1];
  unsigned int *C = &msg_digest[2];
  unsigned int *D = &msg_digest[3];
  int i;
  *A = 0x67452301;
  *B = 0xefcdab89;
  *C = 0x98badcfe;
  *D = 0x10325476;
  string_byte_len = len;
  pstring = (unsigned char *)string;
  for (i = string_byte_len; 64 <= i; i -= 64, pstring += 64)
    MD5_Round_Calculate(pstring, A, B, C, D);
  copy_len = string_byte_len % 64;
  strncpy((char *)padding_message, (char *)pstring, copy_len);
  memset(padding_message + copy_len, 0, 64 - copy_len);
  padding_message[copy_len] |= 0x80;
  if (56 <= copy_len) {
    MD5_Round_Calculate(padding_message, A, B, C, D);
    memset(padding_message, 0, 56);
  }
  string_bit_len = string_byte_len * 8;
  memcpy(&padding_message[56], &string_bit_len, 4);
  if (4294967295U / 8 < string_byte_len) {
    unsigned int high = (string_byte_len - 4294967295U / 8) * 8;
    memcpy(&padding_message[60], &high, 4);
  } else {
    memset(&padding_message[60], 0, 4);
  }
  MD5_Round_Calculate(padding_message, A, B, C, D);
  memcpy(output, msg_digest, 16);
}
```